Skip to main content
This guide walks you through building your first Mizu application. By the end, you’ll have a working web server that handles different routes and returns JSON responses.

Prerequisites

You need Go 1.22 or later installed. Check your version:
go version
# Should show go1.22 or higher
If you need to install Go, visit go.dev/dl.

Create a new project

First, create a directory for your project and initialize a Go module:
mkdir hello-mizu
cd hello-mizu
go mod init hello-mizu
The go mod init command creates a go.mod file that tracks your project’s dependencies. The name hello-mizu can be anything you want.

Install Mizu

Add Mizu as a dependency:
go get github.com/go-mizu/mizu@latest
This downloads Mizu and adds it to your go.mod file.

Write your first app

Create a file named main.go with this code:
package main

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

func main() {
    // Create a new Mizu application
    // This sets up the router, logger, and default middleware
    app := mizu.New()

    // Register a handler for GET requests to "/"
    // When someone visits http://localhost:3000/, this runs
    app.Get("/", func(c *mizu.Ctx) error {
        // Return plain text with status 200 (OK)
        return c.Text(200, "Hello, Mizu!")
    })

    // Start the server on port 3000
    // This blocks until you press Ctrl+C
    app.Listen(":3000")
}
Let’s break down what each part does:
CodePurpose
mizu.New()Creates an app with built-in logging and panic recovery
app.Get("/", ...)Registers a handler for GET requests to the root path
*mizu.CtxThe context object with request data and response helpers
c.Text(200, "...")Sends a text response with HTTP status 200
app.Listen(":3000")Starts the server and listens for connections

Run the app

Start your server:
go run main.go
You’ll see log output showing the server started:
INFO server starting addr=:3000 pid=12345 go_version=go1.22
Open http://localhost:3000 in your browser. You should see β€œHello, Mizu!” on the page. Press Ctrl+C to stop the server. Notice the graceful shutdown messageβ€”Mizu waits for any active requests to finish before exiting.

Add more routes

Let’s expand the app to handle different routes and return JSON. Update your main.go:
package main

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

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

    // Home page
    app.Get("/", func(c *mizu.Ctx) error {
        return c.Text(200, "Welcome to my API!")
    })

    // Return JSON data
    app.Get("/status", func(c *mizu.Ctx) error {
        return c.JSON(200, map[string]string{
            "status":  "running",
            "version": "1.0.0",
        })
    })

    // Capture a path parameter
    // {name} captures that part of the URL
    app.Get("/hello/{name}", func(c *mizu.Ctx) error {
        name := c.Param("name") // Get the captured value
        return c.JSON(200, map[string]string{
            "message": "Hello, " + name + "!",
        })
    })

    // Handle POST requests with JSON body
    app.Post("/echo", func(c *mizu.Ctx) error {
        var input map[string]any
        if err := c.BindJSON(&input, 1<<20); err != nil { // 1MB limit
            return c.JSON(400, map[string]string{"error": err.Error()})
        }
        return c.JSON(200, input)
    })

    app.Listen(":3000")
}
Restart the server (go run main.go) and try:
  • http://localhost:3000/ β†’ β€œWelcome to my API!”
  • http://localhost:3000/status β†’ JSON with status info
  • http://localhost:3000/hello/Alice β†’ {"message":"Hello, Alice!"}
To test the POST endpoint:
curl -X POST http://localhost:3000/echo \
  -H "Content-Type: application/json" \
  -d '{"name":"test"}'

What you learned

You now know how to:
  • Create a Mizu application with mizu.New()
  • Register handlers for different HTTP methods and paths
  • Return text and JSON responses
  • Capture path parameters with {param} syntax
  • Parse JSON request bodies with BindJSON

Next steps