Request Handling
Input Parsing
The req package provides functions for parsing request data into Go structs.
ParseInput
Parses request bodies from JSON, form data, or query parameters based on the Content-Type header:
func MyHandler(c app.Context) error {
var input CreateUserInput
err := c.ParseInput(&input)
if err != nil {
return c.BadRequest(err)
}
return c.JSON(app.M{"input": input})
}ParseInput automatically:
- Decodes JSON bodies (for
application/jsonrequests) - Decodes form/query parameters (for form submissions)
Input Structs and Validation
Define input structs with a Validate() method:
type CreateUserInput struct {
Name string `json:"name"`
Email string `json:"email"`
}
func (i *CreateUserInput) Validate() error {
v := app.NewValidator()
v.Field("name", i.Name).Required().Max(255)
v.Field("email", i.Email).Required().Email()
return v.Validate()
}
func NewCreateUserInput(c app.Context) (*CreateUserInput, error) {
input := &CreateUserInput{}
if err := c.ParseInput(input); err != nil {
return nil, err
}
return input, input.Validate()
}Use with the handler:
func Store(c app.Context) error {
input, err := NewCreateUserInput(c)
if err != nil {
return c.UnprocessableEntity(err)
}
// input is validated and ready to use
}Input Middleware
The router supports an Input middleware that decodes and validates before the handler runs:
r.Post("/users", router.Input(&CreateUserInput{}), handlers.UserStore)The decoded input is available in the handler via c.Input():
func UserStore(c app.Context) error {
input := c.Input().(*CreateUserInput)
// input is already validated
}JSON Body Decoding
For direct JSON decoding without struct binding:
func MyHandler(c app.Context) error {
var data map[string]any
err := c.DecodeJSON(&data)
if err != nil {
return c.BadRequest(err)
}
return c.JSON(data)
}The low-level DecodeJSONBody function enforces:
- 1MB maximum body size
- Rejection of unknown fields
- Single JSON object enforcement
- Detailed error messages
Content-Type Detection
Check what format a client expects:
if c.WantsJSON() {
// Return JSON response
}
if c.WantsHTML() {
// Return HTML response
}
if c.WantsXML() {
// Return XML response
}Check what format the client sent:
if c.HasJSONRequest() { /* JSON body */ }
if c.HasFormDataRequest() { /* multipart form */ }
if c.HasFormURLEncodedRequest() { /* URL-encoded form */ }File Uploads
Handle file uploads with c.Upload():
func Upload(c app.Context) error {
file, err := c.Upload("avatar", "avatars")
if err != nil {
return c.BadRequest(err)
}
return c.JSON(app.M{"path": file.Name()})
}Parameters: the form field name, target directory, and an optional custom filename.