Skip to main content
Mizu is a good fit when you want a lightweight HTTP layer without framework lock-in. Here are common use cases with practical examples.

REST APIs

Build JSON APIs with typed handlers and central error handling. This is Mizu’s sweet spot.
package main

import (
    "github.com/go-mizu/mizu"
)

type User struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

func main() {
    app := mizu.New()

    // List all users
    app.Get("/users", func(c *mizu.Ctx) error {
        users := []User{{ID: "1", Name: "Alice"}}
        return c.JSON(200, users)
    })

    // Get a single user
    app.Get("/users/{id}", func(c *mizu.Ctx) error {
        id := c.Param("id")
        user := User{ID: id, Name: "Alice"}
        return c.JSON(200, user)
    })

    // Create a user
    app.Post("/users", func(c *mizu.Ctx) error {
        var input struct {
            Name  string `json:"name"`
            Email string `json:"email"`
        }
        if err := c.BindJSON(&input, 1<<20); err != nil {
            return c.JSON(400, map[string]string{"error": err.Error()})
        }
        user := User{ID: "123", Name: input.Name, Email: input.Email}
        return c.JSON(201, user)
    })

    // Central error handling
    app.ErrorHandler(func(c *mizu.Ctx, err error) {
        c.Logger().Error("api error", "error", err)
        c.JSON(500, map[string]string{"error": "internal server error"})
    })

    app.Listen(":3000")
}

Backend for SPAs and Mobile

Serve JSON data for React, Vue, or mobile applications. Add CORS headers for cross-origin requests.
func main() {
    app := mizu.New()

    // Simple CORS middleware
    app.Use(func(next mizu.Handler) mizu.Handler {
        return func(c *mizu.Ctx) error {
            c.Header().Set("Access-Control-Allow-Origin", "*")
            c.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")
            c.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")

            // Handle preflight requests
            if c.Request().Method == "OPTIONS" {
                return c.NoContent()
            }
            return next(c)
        }
    })

    // Your API endpoints
    app.Get("/api/data", func(c *mizu.Ctx) error {
        return c.JSON(200, map[string]any{
            "items": []string{"a", "b", "c"},
        })
    })

    app.Listen(":3000")
}

Microservices

Create small, focused services. Mizu’s minimal footprint means fast startup times and low memory usage.
func main() {
    app := mizu.New()

    // Health endpoints for container orchestrators (Kubernetes, ECS, etc.)
    http.Handle("/livez", app.LivezHandler())   // Liveness: is the process alive?
    http.Handle("/readyz", app.ReadyzHandler()) // Readiness: can it handle traffic?

    // Your service's API
    app.Get("/process", func(c *mizu.Ctx) error {
        input := c.Query("data")
        result := processData(input)
        return c.JSON(200, result)
    })

    // Fast startup - suitable for serverless or scaled deployments
    app.Listen(":3000")
}

func processData(input string) map[string]string {
    return map[string]string{"processed": input}
}

Prototypes and Internal Tools

Go from idea to running server quickly. A complete Mizu app fits in a single file.
package main

import "github.com/go-mizu/mizu"

func main() {
    app := mizu.New()

    app.Get("/", func(c *mizu.Ctx) error {
        return c.HTML(200, `
            <h1>Internal Dashboard</h1>
            <ul>
                <li><a href="/status">System Status</a></li>
                <li><a href="/metrics">Metrics</a></li>
            </ul>
        `)
    })

    app.Get("/status", func(c *mizu.Ctx) error {
        return c.JSON(200, map[string]string{
            "database": "connected",
            "cache":    "ready",
        })
    })

    app.Listen(":3000")
}

Server-Side Rendering

Serve HTML pages with Go’s html/template package. Mizu handles routing and static files while you use standard library templates.
package main

import (
    "html/template"
    "github.com/go-mizu/mizu"
)

var tmpl = template.Must(template.New("page").Parse(`
<!DOCTYPE html>
<html>
<head><title>{{.Title}}</title></head>
<body>
    <h1>{{.Title}}</h1>
    <p>Hello, {{.Name}}!</p>
</body>
</html>
`))

func main() {
    app := mizu.New()

    app.Get("/", func(c *mizu.Ctx) error {
        name := c.Query("name")
        if name == "" {
            name = "World"
        }

        c.Header().Set("Content-Type", "text/html; charset=utf-8")
        return tmpl.Execute(c.Writer(), map[string]string{
            "Title": "Welcome",
            "Name":  name,
        })
    })

    // Serve static assets
    app.Static("/static/", http.Dir("./public"))

    app.Listen(":3000")
}

Real-Time Updates with SSE

Stream data to clients using Server-Sent Events. Useful for live dashboards, notifications, and progress updates.
func main() {
    app := mizu.New()

    app.Get("/", func(c *mizu.Ctx) error {
        return c.HTML(200, `
            <h1>Live Updates</h1>
            <div id="updates"></div>
            <script>
                const events = new EventSource('/events');
                events.onmessage = (e) => {
                    document.getElementById('updates').innerHTML += '<p>' + e.data + '</p>';
                };
            </script>
        `)
    })

    app.Get("/events", func(c *mizu.Ctx) error {
        ch := make(chan any)

        // Send updates every second
        go func() {
            defer close(ch)
            for i := 1; i <= 10; i++ {
                ch <- map[string]any{
                    "count":   i,
                    "message": "Update " + fmt.Sprint(i),
                }
                time.Sleep(time.Second)
            }
        }()

        return c.SSE(ch)
    })

    app.Listen(":3000")
}

When Mizu is not the right choice

NeedWhy Mizu may not fitAlternative
WebSocket supportNot built inAdd gorilla/websocket or nhooyr/websocket
Full-stack frameworkNo ORM, auth, adminConsider Buffalo, Beego, or Gin
Convention over configurationMizu is explicitConsider Rails-like frameworks
Automatic bindingNo struct tag magicConsider Echo or Fiber
Mizu stays focused on HTTP routing and request handling. For everything else, pick the Go library you prefer.