// Package mw provides transport-level HTTP middleware for Einherjar services. // // All middleware functions return func(http.Handler) http.Handler and are // composed via [server.WithMiddleware] or chi's Use method. // // # Recommended middleware order (outermost first) // // server.WithMiddleware( // mw.Recover(logger), // mw.RequestID(uuid.NewString), // mw.RequestLogger(logger), // mw.CORS([]string{"https://example.com"}), // ) // // # Request IDs // // [RequestID] always generates a fresh ID. To continue a correlation ID a client // already sent — so a distributed trace survives this boundary — use [RequestIDFrom] // and read the ID off the request in your resolver. The framework does not read the // header or validate the value: what is acceptable is per-service (a typed audit // column rejects what an opaque log accepts), so that policy stays with the caller. // // mw.RequestIDFrom(func(r *http.Request) string { // if id, err := uuid.Parse(r.Header.Get("X-Request-ID")); err == nil { // return id.String() // continue the client's id // } // return uuid.NewString() // otherwise mint one // }) // // # Rate limiting // // // In-memory (default — no extra dependencies) // store := mw.NewInMemoryRateLimiterStore(100, 20) // srv.Use(mw.IPRateLimit(store, logger)) // // // Distributed — swap store, middleware unchanged // store := valkeymw.NewRateLimiterStore(client, 100, 20) // srv.Use(mw.IPRateLimit(store, logger)) package mw