Skip to main content
In this tutorial, you’ll create a simple web application that responds to HTTP requests. We’ll go step by step, explaining each concept as we encounter it. By the end, you’ll understand how web servers work and the core concepts of Mizu.

Prerequisites

Before starting, make sure you have:
  • Go installed (version 1.22 or later)
  • Mizu CLI installed
  • A text editor
Not sure? Run these commands:
go version    # Should show go1.22 or higher
mizu version  # Should show mizu version info

Step 1: Create the Project

Open your terminal and run:
mizu new hello --template minimal
You should see:
Created hello from template minimal
  0 directories, 4 files

Next steps:
  cd hello
  go mod tidy
  mizu dev

Step 2: Enter the Project

cd hello
Look at what was created:
ls -la
Output:
.gitignore
README.md
go.mod
main.go

Step 3: Install Dependencies

go mod tidy
This downloads the Mizu framework and updates go.mod with the correct version.

Step 4: Run the Server

mizu dev
Output:
Starting .
listening on :8080
Your server is running!

Step 5: Test It

Open another terminal (keep the server running) and test with curl:
curl http://localhost:8080
Output:
Hello from hello
Or open http://localhost:8080 in your browser.

Step 6: Stop the Server

Go back to the terminal running mizu dev and press Ctrl+C:
^C
Received interrupt, shutting down...

Understanding the Code

Now let’s look at the code. Open main.go in your editor:
package main

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

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

    app.Get("/", func(c *mizu.Ctx) error {
        return c.Text(200, "Hello from hello\n")
    })

    log.Println("listening on :8080")
    if err := app.Listen(":8080"); err != nil {
        log.Fatal(err)
    }
}

Key Concepts

1. Creating the App
app := mizu.New()
This creates a new Mizu application instance. It sets up the HTTP router and prepares everything for handling requests. 2. Adding a Route
app.Get("/", func(c *mizu.Ctx) error {
    return c.Text(200, "Hello from hello\n")
})
  • app.Get means “handle GET requests”
  • "/" is the path (root URL)
  • The function is your handler - it runs when someone visits /
  • c is the context - it has request info and response methods
  • c.Text(200, ...) sends a plain text response with status code 200
3. Starting the Server
if err := app.Listen(":8080"); err != nil {
    log.Fatal(err)
}
This starts the HTTP server on port 8080 and waits for requests.

Exercise 1: Add a New Route

Let’s add an /about page. Edit main.go:
package main

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

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

    app.Get("/", func(c *mizu.Ctx) error {
        return c.Text(200, "Hello from hello\n")
    })

    // NEW: Add about route
    app.Get("/about", func(c *mizu.Ctx) error {
        return c.Text(200, "This is the about page\n")
    })

    log.Println("listening on :8080")
    if err := app.Listen(":8080"); err != nil {
        log.Fatal(err)
    }
}
Restart the server:
# Press Ctrl+C to stop, then:
mizu dev
Test the new route:
curl http://localhost:8080/about
Output:
This is the about page

Exercise 2: Return JSON

APIs usually return JSON. Let’s add a JSON endpoint. Edit main.go:
package main

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

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

    app.Get("/", func(c *mizu.Ctx) error {
        return c.Text(200, "Hello from hello\n")
    })

    app.Get("/about", func(c *mizu.Ctx) error {
        return c.Text(200, "This is the about page\n")
    })

    // NEW: Add JSON endpoint
    app.Get("/api/status", func(c *mizu.Ctx) error {
        return c.JSON(200, map[string]string{
            "status": "ok",
            "app":    "hello",
        })
    })

    log.Println("listening on :8080")
    if err := app.Listen(":8080"); err != nil {
        log.Fatal(err)
    }
}
Restart and test:
curl http://localhost:8080/api/status
Output:
{"app":"hello","status":"ok"}

Exercise 3: URL Parameters

Let’s create a route that uses URL parameters. Edit main.go:
package main

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

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

    app.Get("/", func(c *mizu.Ctx) error {
        return c.Text(200, "Hello from hello\n")
    })

    // NEW: Route with parameter
    app.Get("/greet/:name", func(c *mizu.Ctx) error {
        name := c.Param("name")
        return c.Text(200, "Hello, "+name+"!\n")
    })

    log.Println("listening on :8080")
    if err := app.Listen(":8080"); err != nil {
        log.Fatal(err)
    }
}
Restart and test:
curl http://localhost:8080/greet/Alice
curl http://localhost:8080/greet/Bob
Output:
Hello, Alice!
Hello, Bob!
The :name in the route is a parameter. Whatever value is in that position gets captured and is available via c.Param("name").

Exercise 4: Query Parameters

Query parameters are the ?key=value part of URLs. Edit main.go:
package main

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

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

    // NEW: Route with query parameter
    app.Get("/search", func(c *mizu.Ctx) error {
        query := c.Query("q")
        if query == "" {
            query = "(no query)"
        }
        return c.Text(200, "Searching for: "+query+"\n")
    })

    log.Println("listening on :8080")
    if err := app.Listen(":8080"); err != nil {
        log.Fatal(err)
    }
}
Restart and test:
curl "http://localhost:8080/search?q=mizu"
curl "http://localhost:8080/search"
Output:
Searching for: mizu
Searching for: (no query)

What You’ve Learned

In this tutorial, you learned:
  1. Create a project with mizu new
  2. Run a server with mizu dev
  3. Add routes with app.Get()
  4. Return text with c.Text()
  5. Return JSON with c.JSON()
  6. Use URL parameters with :name and c.Param()
  7. Use query parameters with c.Query()

Next Steps

You’ve mastered the basics. Here are some options: