> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gocopper.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Middleware

Middleware wraps your handlers to run code before or after them, which is a natural home for concerns like authentication, logging, and transactions. In Copper, a middleware is anything that implements a single-method interface:

```go theme={null}
type Middleware interface {
	Handle(next http.Handler) http.Handler
}
```

### Writing Middleware

A middleware is typically a struct so that its dependencies can be injected by wire. For example, the following middleware protects internal routes with a bearer token:

```go pkg/rockets/middleware.go theme={null}
type NewAuthMiddlewareParams struct {
	Config Config
}

func NewAuthMiddleware(p NewAuthMiddlewareParams) *AuthMiddleware {
	return &AuthMiddleware{config: p.Config}
}

type AuthMiddleware struct {
	config Config
}

func (mw *AuthMiddleware) Handle(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		token := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")

		if token != mw.config.APIToken {
			w.WriteHeader(http.StatusUnauthorized)
			return
		}

		next.ServeHTTP(w, r)
	})
}
```

For simple middleware without dependencies, you may wrap a plain function with `chttp.HandleMiddleware`:

```go theme={null}
var noCacheMW = chttp.HandleMiddleware(func(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Cache-Control", "no-store")
		next.ServeHTTP(w, r)
	})
})
```

### Registering Middleware

You may attach middleware to a single route using the `Middlewares` field:

```go theme={null}
{
	Path:        "/internal/rockets/refuel",
	Methods:     []string{http.MethodPost},
	Handler:     ro.HandleRefuelRockets,
	Middlewares: []chttp.Middleware{ro.authMW},
}
```

To run middleware on every request, add it to `GlobalMiddlewares` in `pkg/app/handler.go`:

```go pkg/app/handler.go theme={null}
GlobalMiddlewares: []chttp.Middleware{
	chttp.SetRequestIDInCtxMiddleware(),
	p.DatabaseTxMW,
	p.RequestLoggerMW,
},
```

Middleware runs in the order it is listed, so the first entry sees the request first. Global middleware always runs before route middleware.

### Built-in Middleware

Copper ships the middleware most apps need, already wired into new projects:

* **`chttp.SetRequestIDInCtxMiddleware()`** puts a unique request ID in the context. You may read it anywhere with `chttp.GetRequestID(ctx)`.
* **`chttp.RequestLoggerMiddleware`** logs every request's method, path, status code, and duration, and also records the built-in `http_requests_total` and `http_request_duration_seconds` Prometheus metrics. See [Metrics](/digging-deeper/metrics).
* **`csql.TxMiddleware`** wraps mutating requests in a database transaction that commits or rolls back based on the response status. See [Transactions](/database/transactions).

<Note>
  Panic recovery is built into the handler itself, so there is no recovery middleware to register. A panicking handler is logged with its stack trace and the client receives a `500`; you never need to add this yourself.
</Note>
