diff --git a/documentation/docs/guides/transformation.mdx b/documentation/docs/guides/transformation.mdx index 6787aeac..46ea24f0 100644 --- a/documentation/docs/guides/transformation.mdx +++ b/documentation/docs/guides/transformation.mdx @@ -35,6 +35,9 @@ func (u *User) InTransform(ctx context.Context) error { u.LastName = strings.TrimSpace(u.LastName) return nil } + +var _ fuego.InTransformer = (*User)(nil) // Ensure *User implements fuego.InTransformer +// This check is a classic example of Go's interface implementation check and we highly recommand to use it ``` In the example above, we have a `User` struct with two fields: `FirstName` and `LastName`. We also have a method called `InTransform` that takes a `context.Context` and returns an `error`. This method is called before the data is unmarshaled into the `User` struct. In this method, we are transforming the `FirstName` to uppercase and trimming any whitespace from the `LastName`. @@ -42,7 +45,7 @@ In the example above, we have a `User` struct with two fields: `FirstName` and ` When using the following controller, the data will be transformed before it is unmarshaled into the `User` struct. ```go -func myController(c fuego.ContextWithBody[User]) (User, error) { +func echoCapitalized(c fuego.ContextWithBody[User]) (User, error) { user, err := c.Body() if err != nil { return User{}, err @@ -53,3 +56,40 @@ func myController(c fuego.ContextWithBody[User]) (User, error) { return u, nil } ``` + +## Recursion + +Transformation is **not recursive**. If you have nested structs, you will need to transform each struct individually. This is done **on purpose** to give you more control over the transformation process: no assumptions are made about how you want to transform your data, no "magic". + +```go +type Address struct { + Street string `json:"street"` + City string `json:"city"` +} + +func (a *Address) InTransform(ctx context.Context) error { + a.Street = strings.TrimSpace(a.Street) + a.City = strings.ToUpper(a.City) + return nil +} + +type User struct { + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + // highlight-next-line + Address Address `json:"address"` // Nested struct +} + +func (u *User) InTransform(ctx context.Context) error { + u.FirstName = strings.ToUpper(u.FirstName) + u.LastName = strings.TrimSpace(u.LastName) + +// highlight-next-line + err := u.Address.InTransform(ctx) // Transform the nested struct + if err != nil { + return err + } + + return nil +} +``` diff --git a/documentation/src/components/FlowChart.js b/documentation/src/components/FlowChart.js index 82efb16f..c05a9fd1 100644 --- a/documentation/src/components/FlowChart.js +++ b/documentation/src/components/FlowChart.js @@ -32,6 +32,7 @@ subgraph fuego click ErrorHandler "/fuego/docs/guides/errors" "Error Handling" end +ErrorHandler -- JSON{b:'Error!'} --> resp(Response) Serialization -- JSON{b:'My Response!'} --> resp(Response) Controller -. JSON{b:'Custom Response!'} .-> resp(Response)