feat(web): httputil.WithStatus — configurable success status on the handler adapters (v1.5.0)
This commit is contained in:
+16
-9
@@ -14,9 +14,11 @@ import (
|
||||
// - Decodes the JSON request body into Req.
|
||||
// - Validates Req using the provided [valid.Validator].
|
||||
// - Calls fn with the request context and decoded Req.
|
||||
// - Encodes Res as JSON with HTTP 200 on success.
|
||||
// - Encodes Res as JSON on success — HTTP 200 by default, or the code given via
|
||||
// [WithStatus] (e.g. WithStatus(http.StatusCreated) for a resource-creating POST).
|
||||
// - On error: logs via [Error] (level derived from HTTP status) and writes the standardized JSON body.
|
||||
func Handle[Req, Res any](v valid.Validator, logger logging.Logger, fn func(ctx context.Context, req Req) (Res, error)) http.HandlerFunc {
|
||||
func Handle[Req, Res any](v valid.Validator, logger logging.Logger, fn func(ctx context.Context, req Req) (Res, error), opts ...Option) http.HandlerFunc {
|
||||
status := resolveStatus(http.StatusOK, opts)
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req Req
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
@@ -32,28 +34,33 @@ func Handle[Req, Res any](v valid.Validator, logger logging.Logger, fn func(ctx
|
||||
Error(logger, w, r, err)
|
||||
return
|
||||
}
|
||||
JSON(w, http.StatusOK, res)
|
||||
JSON(w, status, res)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleNoBody adapts a typed function with no request body (GET, HEAD).
|
||||
// Calls fn with the request context; encodes the result as JSON with HTTP 200.
|
||||
// Calls fn with the request context; encodes the result as JSON — HTTP 200 by
|
||||
// default, or the code given via [WithStatus].
|
||||
// On error: logs via [Error] and writes the standardized JSON body.
|
||||
func HandleNoBody[Res any](logger logging.Logger, fn func(ctx context.Context) (Res, error)) http.HandlerFunc {
|
||||
func HandleNoBody[Res any](logger logging.Logger, fn func(ctx context.Context) (Res, error), opts ...Option) http.HandlerFunc {
|
||||
status := resolveStatus(http.StatusOK, opts)
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
res, err := fn(r.Context())
|
||||
if err != nil {
|
||||
Error(logger, w, r, err)
|
||||
return
|
||||
}
|
||||
JSON(w, http.StatusOK, res)
|
||||
JSON(w, status, res)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleEmpty adapts a typed function with a request body but no response body.
|
||||
// Decodes and validates Req, calls fn, returns 204 No Content on success.
|
||||
// Decodes and validates Req, calls fn, and writes a body-less success — 204 No
|
||||
// Content by default, or the code given via [WithStatus] (e.g.
|
||||
// WithStatus(http.StatusAccepted) for async processing).
|
||||
// On error: logs via [Error] and writes the standardized JSON body.
|
||||
func HandleEmpty[Req any](v valid.Validator, logger logging.Logger, fn func(ctx context.Context, req Req) error) http.HandlerFunc {
|
||||
func HandleEmpty[Req any](v valid.Validator, logger logging.Logger, fn func(ctx context.Context, req Req) error, opts ...Option) http.HandlerFunc {
|
||||
status := resolveStatus(http.StatusNoContent, opts)
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req Req
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
@@ -68,6 +75,6 @@ func HandleEmpty[Req any](v valid.Validator, logger logging.Logger, fn func(ctx
|
||||
Error(logger, w, r, err)
|
||||
return
|
||||
}
|
||||
NoContent(w)
|
||||
w.WriteHeader(status)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user