feat(httpmw): initial stable release v0.9.0
Standalone net/http middleware for panic recovery, CORS, request ID injection, and request logging. What's included: - Recover(): panic -> 500, captures debug.Stack, no logger required - CORS(origins): OPTIONS 204 preflight, origin allowlist, package-wide method/header constants - RequestID(generator): injects ID via logz.WithRequestID, sets X-Request-ID response header - RequestLogger(logger): logs method/path/status/latency/request_id; Error for 5xx, Info otherwise - Logger interface: Info, Error, With — duck-typed; satisfied by logz.Logger - StatusRecorder: exported http.ResponseWriter wrapper that captures written status code - Direct logz import for context helpers (documented exception to ADR-001) Tested-via: todo-api POC integration Reviewed-against: docs/adr/
This commit is contained in:
25
CHANGELOG.md
Normal file
25
CHANGELOG.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this module will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this module adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.9.0] - 2026-03-18
|
||||
|
||||
### Added
|
||||
|
||||
- `Recover() func(http.Handler) http.Handler` — catches panics from inner handlers via `defer/recover`, captures the stack trace with `debug.Stack`, and writes HTTP 500; requires no configuration or logger injection
|
||||
- `CORS(origins []string) func(http.Handler) http.Handler` — sets `Access-Control-Allow-Origin`, `Access-Control-Allow-Methods` (`GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS`), and `Access-Control-Allow-Headers` (`Content-Type, Authorization, X-Request-ID`) for matching origins; short-circuits OPTIONS preflight requests with HTTP 204; pass `[]string{"*"}` for development environments
|
||||
- `RequestID(generator func() string) func(http.Handler) http.Handler` — calls `generator` (e.g. `uuid.NewString`) to produce a unique ID per request, stores it in the context via `logz.WithRequestID`, and writes it to the `X-Request-ID` response header
|
||||
- `RequestLogger(logger Logger) func(http.Handler) http.Handler` — logs method, path, status code, latency, and request ID after the inner handler returns; uses `logger.Error` for 5xx responses and `logger.Info` for all others; reads the request ID from context via `logz.GetRequestID`
|
||||
- `Logger` interface — duck-typed logger accepted by `RequestLogger`; satisfied by `logz.Logger`: `Info(msg string, args ...any)`, `Error(msg string, err error, args ...any)`, `With(args ...any) Logger`
|
||||
- `StatusRecorder` struct — exported `http.ResponseWriter` wrapper that captures the written status code in its `Status` field; used internally by `RequestLogger` and available for custom logging middleware
|
||||
|
||||
### Design Notes
|
||||
|
||||
- `RequestID` and `RequestLogger` use `logz.WithRequestID` and `logz.GetRequestID` directly rather than a locally defined context key; this ensures the request ID is visible to any `logz.Logger` that calls `.WithContext(ctx)` downstream, which would break if the key were re-implemented here.
|
||||
- `Recover` intentionally requires no logger injection in this release: it captures the stack trace but does not log it, keeping the middleware usable with zero configuration; logger injection is deferred to a future release.
|
||||
- No middleware is installed by default; the package exports independent functions and the application chooses the chain and order (recommended: `Recover` → `RequestID` → `RequestLogger` → `CORS`).
|
||||
|
||||
[0.9.0]: https://code.nochebuena.dev/go/httpmw/releases/tag/v0.9.0
|
||||
Reference in New Issue
Block a user