Documentation Index Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
Use this file to discover all available pages before exploring further.
A handler is a function that processes an HTTP request and produces a response. Every route in your Mizu app connects a URL pattern to a handler function.
The handler signature
Every Mizu handler has the same signature:
Part Purpose c *mizu.CtxThe context - contains request data and response helpers errorReturn value - nil for success, an error to trigger error handling
This signature is Mizu’s Handler type:
type Handler func ( * mizu . Ctx ) error
Writing handlers
Basic handler
func home ( c * mizu . Ctx ) error {
return c . Text ( 200 , "Hello, Mizu!" )
}
func main () {
app := mizu . New ()
app . Get ( "/" , home )
app . Listen ( ":3000" )
}
The handler:
Receives the context c with request info
Returns c.Text(200, "...") which sends a response
The error return is nil (success) because c.Text returns nil on success
Inline handlers
For simple routes, define handlers inline:
app . Get ( "/ping" , func ( c * mizu . Ctx ) error {
return c . Text ( 200 , "pong" )
})
Reading request data
Use context methods to read from the request:
func getUser ( c * mizu . Ctx ) error {
// Path parameter: /users/{id}
id := c . Param ( "id" )
// Query parameter: ?fields=name,email
fields := c . Query ( "fields" )
// Header
auth := c . Request (). Header . Get ( "Authorization" )
return c . JSON ( 200 , map [ string ] string {
"id" : id ,
"fields" : fields ,
})
}
func createUser ( c * mizu . Ctx ) error {
// Define the expected input structure
var input struct {
Name string `json:"name"`
Email string `json:"email"`
}
// Parse JSON body (1MB limit)
if err := c . BindJSON ( & input , 1 << 20 ); err != nil {
return c . JSON ( 400 , map [ string ] string { "error" : err . Error ()})
}
// Validate
if input . Name == "" {
return c . JSON ( 400 , map [ string ] string { "error" : "name is required" })
}
// Process and respond
user := User { ID : "123" , Name : input . Name , Email : input . Email }
return c . JSON ( 201 , user )
}
Returning errors
Handlers can return errors to indicate failures:
func getUser ( c * mizu . Ctx ) error {
id := c . Param ( "id" )
user , err := database . FindUser ( id )
if err != nil {
return err // Passed to error handler
}
return c . JSON ( 200 , user )
}
When a handler returns a non-nil error:
Mizu calls your ErrorHandler if you set one
Otherwise, it logs the error and returns 500
Set a global error handler:
app . ErrorHandler ( func ( c * mizu . Ctx , err error ) {
c . Logger (). Error ( "request failed" , "error" , err )
c . JSON ( 500 , map [ string ] string { "error" : "internal error" })
})
Response methods
Handlers send responses using context methods:
// Plain text
return c . Text ( 200 , "OK" )
// JSON
return c . JSON ( 200 , user )
// HTML
return c . HTML ( 200 , "<h1>Welcome</h1>" )
// Redirect
return c . Redirect ( 302 , "/login" )
// No content (204)
return c . NoContent ()
// File
return c . File ( 200 , "./public/logo.png" )
// Download (forces browser download)
return c . Download ( 200 , "./report.csv" , "report.csv" )
Handler patterns
Early returns for validation
func createPost ( c * mizu . Ctx ) error {
var input PostInput
if err := c . BindJSON ( & input , 1 << 20 ); err != nil {
return c . JSON ( 400 , map [ string ] string { "error" : "invalid JSON" })
}
if input . Title == "" {
return c . JSON ( 400 , map [ string ] string { "error" : "title required" })
}
if len ( input . Title ) > 100 {
return c . JSON ( 400 , map [ string ] string { "error" : "title too long" })
}
// All validation passed - create the post
post := createPost ( input )
return c . JSON ( 201 , post )
}
Separating concerns
Keep handlers thin by extracting business logic:
// Handler: HTTP layer
func createUser ( c * mizu . Ctx ) error {
var input CreateUserInput
if err := c . BindJSON ( & input , 1 << 20 ); err != nil {
return c . JSON ( 400 , map [ string ] string { "error" : err . Error ()})
}
user , err := userService . Create ( input ) // Business logic
if err != nil {
return err
}
return c . JSON ( 201 , user )
}
Handler factories
Create handlers that share configuration:
func makeGreeter ( greeting string ) mizu . Handler {
return func ( c * mizu . Ctx ) error {
name := c . Param ( "name" )
return c . Text ( 200 , greeting + ", " + name + "!" )
}
}
func main () {
app := mizu . New ()
app . Get ( "/hello/{name}" , makeGreeter ( "Hello" ))
app . Get ( "/hi/{name}" , makeGreeter ( "Hi" ))
app . Listen ( ":3000" )
}
Summary
Concept Description Signature func(c *mizu.Ctx) errorContext Request data and response helpers Return nil Success - response already sent Return error Triggers error handler Response Use c.Text(), c.JSON(), etc.
Next steps
Context Deeper dive into request/response context.
Response All the ways to send responses.