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

# Healthcheck

> Health check endpoints middleware for Kubernetes liveness and readiness probes.

## Overview

The `healthcheck` middleware provides liveness and readiness probe endpoints for container orchestration platforms like Kubernetes. It supports custom health checks for databases, caches, and other dependencies.

Use it when you need:

* Kubernetes liveness/readiness probes
* Load balancer health checks
* Dependency health monitoring

## Installation

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/healthcheck"
```

## Quick Start

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

// Register default endpoints
healthcheck.Register(app, healthcheck.Options{})

// Or add custom checks
healthcheck.Register(app, healthcheck.Options{
    Checks: []healthcheck.Check{
        healthcheck.DBCheck("postgres", db.Ping),
    },
})
```

## Configuration

### Options

| Option          | Type      | Default      | Description             |
| --------------- | --------- | ------------ | ----------------------- |
| `LivenessPath`  | `string`  | `"/healthz"` | Liveness endpoint path  |
| `ReadinessPath` | `string`  | `"/readyz"`  | Readiness endpoint path |
| `Checks`        | `[]Check` | `[]`         | Health checks to run    |

### Check

| Field     | Type                          | Description              |
| --------- | ----------------------------- | ------------------------ |
| `Name`    | `string`                      | Check name for reporting |
| `Check`   | `func(context.Context) error` | Check function           |
| `Timeout` | `time.Duration`               | Check timeout            |

## Examples

### Basic Endpoints

```go theme={null}
healthcheck.Register(app, healthcheck.Options{})
// Creates:
// GET /healthz - liveness probe
// GET /readyz - readiness probe
```

### With Database Check

```go theme={null}
healthcheck.Register(app, healthcheck.Options{
    Checks: []healthcheck.Check{
        {
            Name: "postgres",
            Check: func(ctx context.Context) error {
                return db.PingContext(ctx)
            },
            Timeout: 5 * time.Second,
        },
    },
})
```

### Multiple Dependencies

```go theme={null}
healthcheck.Register(app, healthcheck.Options{
    Checks: []healthcheck.Check{
        healthcheck.DBCheck("postgres", db.Ping),
        {
            Name: "redis",
            Check: func(ctx context.Context) error {
                return redisClient.Ping(ctx).Err()
            },
            Timeout: 2 * time.Second,
        },
        {
            Name: "elasticsearch",
            Check: func(ctx context.Context) error {
                _, _, err := esClient.Ping()
                return err
            },
            Timeout: 3 * time.Second,
        },
    },
})
```

### Custom Paths

```go theme={null}
healthcheck.Register(app, healthcheck.Options{
    LivenessPath:  "/health/live",
    ReadinessPath: "/health/ready",
})
```

### Standalone Handlers

```go theme={null}
// Just liveness
app.Get("/healthz", healthcheck.Liveness())

// Just readiness with checks
app.Get("/readyz", healthcheck.Readiness(
    healthcheck.Check{Name: "db", Check: db.Ping},
))
```

### Using DBCheck Helper

```go theme={null}
check := healthcheck.DBCheck("postgres", func(ctx context.Context) error {
    return db.PingContext(ctx)
})
// Creates check with 5s default timeout
```

## API Reference

### Functions

```go theme={null}
// Register adds health check routes to the app
func Register(app *mizu.App, opts Options)

// Liveness returns a simple liveness handler
func Liveness() mizu.Handler

// Readiness returns a readiness handler with checks
func Readiness(checks ...Check) mizu.Handler

// New creates a combined health handler
func New(opts Options) mizu.Handler

// DBCheck creates a database check with default timeout
func DBCheck(name string, pingFn func(context.Context) error) Check
```

## Response Format

### Liveness Response

```
ok
```

### Readiness Response (Success)

```json theme={null}
{
    "status": "ok",
    "checks": {
        "postgres": "ok",
        "redis": "ok"
    }
}
```

### Readiness Response (Failure)

```json theme={null}
{
    "status": "error",
    "checks": {
        "postgres": "ok",
        "redis": "connection failed"
    }
}
```

## HTTP Status Codes

| Code | Meaning                               |
| ---- | ------------------------------------- |
| 200  | Healthy                               |
| 503  | Unhealthy (one or more checks failed) |

## Kubernetes Configuration

```yaml theme={null}
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /readyz
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
```

## Technical Details

### Implementation Architecture

The healthcheck middleware is designed with the following technical characteristics:

* **Concurrent Check Execution**: All health checks run in parallel using goroutines with a `sync.WaitGroup` to coordinate execution
* **Thread-Safe Results**: A `sync.Mutex` protects the results map during concurrent check execution
* **Context-Based Timeouts**: Each check runs with its own `context.WithTimeout` to prevent hanging checks
* **Default Timeout**: If no timeout is specified, checks default to 5 seconds
* **Status Code Mapping**: Returns HTTP 200 for healthy, HTTP 503 for unhealthy states

### Core Components

1. **Check Struct**: Defines a health check with name, check function, and timeout
2. **Status Struct**: JSON response structure with overall status and individual check results
3. **Options Struct**: Configuration for endpoint paths and checks list
4. **Liveness Handler**: Simple text response ("ok") with no dependency checks
5. **Readiness Handler**: Executes all checks concurrently and aggregates results

### Helper Functions

* **DBCheck**: Creates a database health check with a 5-second default timeout
* **HTTPCheck**: Creates an HTTP endpoint health check with a 10-second default timeout
* **New**: Creates a combined handler that routes to liveness or readiness based on path
* **Register**: Convenience function to register both endpoints on a router

## Best Practices

* Keep liveness checks simple (no external dependencies)
* Include all critical dependencies in readiness checks
* Set appropriate timeouts for each check
* Use readiness to control traffic during startup/shutdown

## Testing

### Test Cases

| Test Case                        | Description                                 | Expected Behavior                                                         |
| -------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------- |
| `TestLiveness`                   | Basic liveness endpoint test                | Returns HTTP 200 with "ok" text response                                  |
| `TestReadiness/no_checks`        | Readiness with no checks configured         | Returns HTTP 200 with "ok" text response                                  |
| `TestReadiness/all_healthy`      | Readiness with all checks passing           | Returns HTTP 200 with JSON status "ok" and all checks marked "ok"         |
| `TestReadiness/one_unhealthy`    | Readiness with one failing check            | Returns HTTP 503 with JSON status "error" and error message in checks     |
| `TestReadiness_Timeout`          | Check that exceeds timeout                  | Returns HTTP 503 due to context deadline exceeded                         |
| `TestNew/liveness`               | Combined handler with custom liveness path  | Routes to liveness handler and returns HTTP 200                           |
| `TestNew/readiness`              | Combined handler with custom readiness path | Routes to readiness handler and returns HTTP 200 with checks              |
| `TestRegister/default_liveness`  | Register with default paths (/healthz)      | Liveness endpoint returns HTTP 200                                        |
| `TestRegister/default_readiness` | Register with default paths (/readyz)       | Readiness endpoint returns HTTP 200 with checks                           |
| `TestDBCheck`                    | DBCheck helper function                     | Creates check with name "postgres", 5s timeout, and executes successfully |

## Related Middlewares

* [pprof](/middlewares/pprof) - Profiling endpoints
* [metrics](/middlewares/metrics) - Metrics collection
* [version](/middlewares/version) - API versioning
