httputil depends on xerrors (Tier 0) and valid (Tier 1), placing it at Tier 2. No infrastructure or lifecycle dependencies exist in this module.
28 lines
2.7 KiB
Markdown
28 lines
2.7 KiB
Markdown
# 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
|
|
|
|
- `Handle[Req, Res any](v valid.Validator, fn func(ctx context.Context, req Req) (Res, error)) http.HandlerFunc` — decodes the JSON request body into `Req`, validates it with the injected `Validator`, calls `fn`, and encodes the result as JSON with HTTP 200; invalid JSON returns 400
|
|
- `HandleNoBody[Res any](fn func(ctx context.Context) (Res, error)) http.HandlerFunc` — no body decode or validation; calls `fn` and encodes the result as JSON with HTTP 200; intended for GET and DELETE endpoints
|
|
- `HandleEmpty[Req any](v valid.Validator, fn func(ctx context.Context, req Req) error) http.HandlerFunc` — decodes and validates the JSON request body, calls `fn`, returns HTTP 204 on success; intended for write endpoints with no response body
|
|
- `HandlerFunc` type — `func(w http.ResponseWriter, r *http.Request) error`; implements `http.Handler`; on non-nil return, routes the error through `Error(w, err)` for automatic status mapping
|
|
- `JSON(w http.ResponseWriter, status int, v any)` — encodes `v` as JSON and writes it with the given status code; sets `Content-Type: application/json`
|
|
- `NoContent(w http.ResponseWriter)` — writes HTTP 204 No Content
|
|
- `Error(w http.ResponseWriter, err error)` — maps `*xerrors.Err` codes to HTTP status codes and writes a `{"code": "...", "message": "..."}` JSON body; includes any extra fields from the error; falls back to 500 for unknown errors
|
|
- `xerrors.Code` to HTTP status mapping (12 codes): `ErrInvalidInput` → 400, `ErrUnauthorized` → 401, `ErrPermissionDenied` → 403, `ErrNotFound` → 404, `ErrAlreadyExists` → 409, `ErrGone` → 410, `ErrPreconditionFailed` → 412, `ErrRateLimited` → 429, `ErrInternal` → 500, `ErrNotImplemented` → 501, `ErrUnavailable` → 503, `ErrDeadlineExceeded` → 504
|
|
|
|
### Design Notes
|
|
|
|
- Business functions wrapped by `Handle`, `HandleNoBody`, and `HandleEmpty` have no `http.ResponseWriter` or `*http.Request` in their signatures, making them callable directly in unit tests with `context.Background()` and a typed request value.
|
|
- `Error` is the single translation point from `xerrors.Code` to HTTP status; all handler adapters route through it, preventing fragmented status code contracts across the codebase.
|
|
- Validation is injected via `valid.Validator` and runs before the business function is called; an invalid request never reaches business logic.
|
|
|
|
[0.9.0]: https://code.nochebuena.dev/go/httputil/releases/tag/v0.9.0
|