> ## 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.

# App

> The main entry point that runs your Mizu application.

An `App` is the main entry point for your web server. It wraps an HTTP server, manages its lifecycle, and handles graceful shutdown when the process receives a stop signal.

## What an App does

When you create an app with `mizu.New()`, you get:

| Component             | Description                                                  |
| --------------------- | ------------------------------------------------------------ |
| **Router**            | Embedded, so you can call `app.Get()`, `app.Post()` directly |
| **Logger**            | Request logging enabled by default                           |
| **Panic recovery**    | Catches panics in handlers, prevents crashes                 |
| **Graceful shutdown** | Drains active requests before stopping                       |

## Create an app

Every Mizu project starts by creating an `App`:

```go theme={null}
package main

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

func main() {
    // Create a new app with default settings
    app := mizu.New()

    // Define a route - App embeds Router, so this works directly
    app.Get("/", func(c *mizu.Ctx) error {
        return c.Text(200, "Hello, Mizu!")
    })

    // Start the HTTP server on port 3000
    // This blocks until you press Ctrl+C
    app.Listen(":3000")
}
```

When this runs:

1. `mizu.New()` creates an app with a router and default logger
2. `app.Get("/", ...)` registers a handler for GET requests to "/"
3. `app.Listen(":3000")` starts the HTTP server

The terminal shows startup logs:

```
INFO server starting addr=:3000 pid=12345 go_version=go1.22
```

## Starting the server

Mizu provides three ways to start your server:

```go theme={null}
// 1. Listen on a TCP address (most common)
app.Listen(":3000")

// 2. Listen with TLS (HTTPS)
app.ListenTLS(":443", "cert.pem", "key.pem")

// 3. Use an existing listener (advanced)
listener, _ := net.Listen("tcp", ":3000")
app.Serve(listener)
```

All three methods block until the server stops. They also handle graceful shutdown when the process receives SIGINT (Ctrl+C) or SIGTERM.

## Configuration

Configure the app by setting fields after creation:

```go theme={null}
app := mizu.New()

// Shutdown timeout: how long to wait for active requests
// Default: 15 seconds
app.ShutdownTimeout = 30 * time.Second
```

| Field             | Default    | Description                                                          |
| ----------------- | ---------- | -------------------------------------------------------------------- |
| `ShutdownTimeout` | 15 seconds | Maximum time to wait for active requests to complete during shutdown |

## Graceful shutdown

When your app receives a stop signal (SIGINT or SIGTERM):

1. **New connections refused** - The server stops accepting new connections
2. **Active requests complete** - Running requests continue until finished (up to `ShutdownTimeout`)
3. **Clean exit** - Server exits with success status

This prevents dropped connections during deployments. Your load balancer can redirect traffic while the old instance drains.

```
INFO shutdown initiated
INFO server stopped gracefully duration=1.234s
```

If requests don't finish within `ShutdownTimeout`, they're terminated.

## Health check endpoints

Mizu provides two health check handlers for load balancers and orchestrators like Kubernetes:

```go theme={null}
app := mizu.New()

// Liveness probe: is the process alive?
// Always returns 200 OK
http.Handle("/livez", app.LivezHandler())

// Readiness probe: can it handle traffic?
// Returns 200 normally, 503 during shutdown
http.Handle("/readyz", app.ReadyzHandler())

app.Listen(":3000")
```

| Endpoint  | Normal | During Shutdown         |
| --------- | ------ | ----------------------- |
| `/livez`  | 200 OK | 200 OK                  |
| `/readyz` | 200 OK | 503 Service Unavailable |

**How they differ:**

* **Liveness** (`/livez`): "Is the process running?" Used by Kubernetes to decide if the pod should be restarted
* **Readiness** (`/readyz`): "Can it handle traffic?" Used by load balancers to route traffic

During graceful shutdown, `/readyz` returns 503 so load balancers stop sending new traffic, while `/livez` continues returning 200 so the pod isn't killed prematurely.

## Access the underlying server

For advanced configuration, access the `http.Server` instance:

```go theme={null}
app := mizu.New()

// Configure routes...
app.Get("/", handler)

// Access the server (available after calling Listen/ListenTLS/Serve)
// Can be used to configure TLSConfig, ConnState callbacks, etc.
srv := app.Server()
```

## Complete example

```go theme={null}
package main

import (
    "net/http"
    "time"

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

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

    // Configure shutdown timeout
    app.ShutdownTimeout = 30 * time.Second

    // Health check endpoints
    http.Handle("/livez", app.LivezHandler())
    http.Handle("/readyz", app.ReadyzHandler())

    // Your API routes
    app.Get("/", func(c *mizu.Ctx) error {
        return c.JSON(200, map[string]string{"status": "ok"})
    })

    app.Group("/api", func(r *mizu.Router) {
        r.Get("/users", listUsers)
        r.Post("/users", createUser)
    })

    // Set 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"})
    })

    // Start server
    app.Listen(":3000")
}

func listUsers(c *mizu.Ctx) error { return c.JSON(200, []string{}) }
func createUser(c *mizu.Ctx) error { return c.JSON(201, nil) }
```

## Next steps

<CardGroup cols={2}>
  <Card title="Routing" icon="route" href="/guides/concepts/routing">
    Define URLs and HTTP methods.
  </Card>

  <Card title="Handler" icon="code" href="/guides/concepts/handler">
    Write request handling logic.
  </Card>
</CardGroup>
