Documentation
¶
Overview ¶
Package httpapi provides helpers for building JSON HTTP APIs.
It covers request decoding, structured error responses, and response writing. Error handling maps errs.Error domain errors to HTTP status codes and structured JSON bodies without leaking internal details to clients.
Request decoding ¶
body, err := httpapi.DecodeJSON[CreateUserRequest](r)
if err != nil {
httpapi.HandleErr(w, r, err, nil)
return
}
Error handling ¶
HandleErr maps any error to a JSON response. It understands errs.Error values extracted from the chain, JSON decode errors, and falls back to 500 for unknown errors. App-specific error codes are supported via extraCodes:
var appCodes = map[string]int{
"payment_failed": http.StatusPaymentRequired,
}
httpapi.HandleErr(w, r, err, appCodes)
For validator.ValidationError from request validation, use HandleValidationError to tag each field error with its request location (body, query, path, header):
httpapi.HandleValidationError(w, r, httpapi.LocationBody, ve)
Response writing ¶
httpapi.Ok(w, data) // 200 httpapi.Created(w, data) // 201 httpapi.NoContent(w) // 204
Index ¶
- func Accepted(w http.ResponseWriter, data any)
- func BadRequest(w http.ResponseWriter, data any)
- func Conflict(w http.ResponseWriter, data any)
- func Created(w http.ResponseWriter, data any)
- func DecodeJSON[T any](r *http.Request) (T, error)
- func Error(w http.ResponseWriter, statusCode int, code, message string)
- func Forbidden(w http.ResponseWriter, data any)
- func HandleErr(w http.ResponseWriter, r *http.Request, err error, extraCodes map[string]int)
- func HandleValidationError(w http.ResponseWriter, r *http.Request, loc Location, ...)
- func InternalServerError(w http.ResponseWriter, data any)
- func IsJSONDecodeError(err error) bool
- func NoContent(w http.ResponseWriter)
- func NotFound(w http.ResponseWriter, data any)
- func Ok(w http.ResponseWriter, data any)
- func ParseCursorPager(r *http.Request, opts ...pagination.CursorOption) (pagination.CursorPager, error)
- func ParseOffsetPager(r *http.Request, opts ...pagination.OffsetOption) (pagination.OffsetPager, error)
- func ParseSort(r *http.Request, allowed map[string]string) (sorting.Sorts, error)
- func Response(w http.ResponseWriter, statusCode int, data any)
- func TooManyRequests(w http.ResponseWriter, data any)
- func Unauthorized(w http.ResponseWriter, data any)
- func UnprocessableEntity(w http.ResponseWriter, data any)
- type ErrorResponse
- type FieldErrorResponse
- type Location
- type ValidationErrorResponse
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BadRequest ¶
func BadRequest(w http.ResponseWriter, data any)
BadRequest writes a 400 JSON response.
func DecodeJSON ¶
DecodeJSON decodes the JSON request body into T. Returns an error if the body is missing, malformed, or cannot be decoded.
func Error ¶
func Error(w http.ResponseWriter, statusCode int, code, message string)
Error writes a JSON error response with the given status code, error code, and message.
func Forbidden ¶
func Forbidden(w http.ResponseWriter, data any)
Forbidden writes a 403 JSON response.
func HandleErr ¶
HandleErr maps an error to an HTTP status code and writes a structured JSON response. extraCodes extends or overrides the default code→status mapping for app-specific error codes. Pass nil if no custom codes are needed.
func HandleValidationError ¶
func HandleValidationError( w http.ResponseWriter, r *http.Request, loc Location, ve *validator.ValidationError, )
HandleValidationError writes a 422 JSON response for a ValidationError, tagging every field error with the given request location (body, query, path, or header). The trace_id is populated from the active OTEL span when present.
func InternalServerError ¶
func InternalServerError(w http.ResponseWriter, data any)
InternalServerError writes a 500 JSON response.
func IsJSONDecodeError ¶
IsJSONDecodeError reports whether err originated from JSON decoding: syntax errors, type mismatches, or an empty/truncated body.
func NoContent ¶
func NoContent(w http.ResponseWriter)
NoContent writes a 204 response with no body.
func ParseCursorPager ¶
func ParseCursorPager(r *http.Request, opts ...pagination.CursorOption) (pagination.CursorPager, error)
ParseCursorPager parses ?cursor and ?limit query parameters into a pagination.CursorPager. Invalid or absent values fall back to package defaults. Pass pagination.WithDefaultLimit or pagination.WithMaxLimit to override bounds.
?cursor=xxx&limit=20 → CursorPager{Cursor:"xxx", Limit:20}
func ParseOffsetPager ¶
func ParseOffsetPager(r *http.Request, opts ...pagination.OffsetOption) (pagination.OffsetPager, error)
ParseOffsetPager parses ?page and ?page_size query parameters into a pagination.OffsetPager. Invalid or absent values fall back to package defaults. Pass pagination.WithDefaultPageSize or pagination.WithMaxPageSize to override bounds.
?page=2&page_size=50 → OffsetPager{Page:2, PageSize:50}
func ParseSort ¶
ParseSort parses the ?sort query parameter into a sorting.Sorts slice.
Format: comma-separated field names; prefix "-" for descending order.
?sort=-created_at,name → ORDER BY created_at DESC, full_name ASC
allowed maps API field names to domain field names, e.g.:
map[string]string{"createdAt": "created_at", "name": "full_name"}
Returns nil, nil when the parameter is absent. Returns an error for unknown fields or invalid input.
func Response ¶
func Response(w http.ResponseWriter, statusCode int, data any)
Response writes a JSON response with the given status code.
func TooManyRequests ¶
func TooManyRequests(w http.ResponseWriter, data any)
TooManyRequests writes a 429 JSON response.
func Unauthorized ¶
func Unauthorized(w http.ResponseWriter, data any)
Unauthorized writes a 401 JSON response.
func UnprocessableEntity ¶
func UnprocessableEntity(w http.ResponseWriter, data any)
UnprocessableEntity writes a 422 JSON response.
Types ¶
type ErrorResponse ¶
type ErrorResponse struct {
Code string `json:"code"`
Message string `json:"message"`
Details string `json:"details,omitempty"`
TraceID string `json:"trace_id,omitempty"`
}
ErrorResponse is the base error response body shape.
type FieldErrorResponse ¶
type FieldErrorResponse struct {
Location string `json:"location,omitempty"`
Field string `json:"field"`
Code string `json:"code"`
Message string `json:"message"`
Params map[string]any `json:"params,omitempty"`
}
FieldErrorResponse describes a single field-level validation error in an HTTP response.
type Location ¶
type Location string
Location identifies where in an HTTP request a field error originated. Values mirror the OpenAPI "in" vocabulary.
type ValidationErrorResponse ¶
type ValidationErrorResponse struct {
ErrorResponse
Errors []FieldErrorResponse `json:"errors"`
}
ValidationErrorResponse is used for 422 responses; Errors is always a non-nil array.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package httpapitest provides test helpers for the httpapi package.
|
Package httpapitest provides test helpers for the httpapi package. |