Help us shape the future of Go! Take the 2026 Go Developer Survey

httpapi

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package httpapi holds the request and response plumbing shared by the module's HTTP endpoints, following the API design standard: the standard error format, strict JSON decoding, request IDs, and finding the real client behind a trusted proxy.

Index

Constants

View Source
const ForwardedUserAgentHeader = "X-Forwarded-User-Agent"

ForwardedUserAgentHeader carries the real client's User-Agent from a trusted proxy (Next.js), whose own User-Agent is in User-Agent.

View Source
const MaxBodySize = 64 << 10

MaxBodySize is the largest request body the module reads.

View Source
const RequestIDHeader = "X-Request-ID"

RequestIDHeader carries the request ID in requests and responses.

Variables

View Source
var (
	ErrBadRequest = errors.New("malformed request body")
	ErrTooLarge   = errors.New("request body too large")
)

Decoding errors, for mapping to responses.

Functions

func Client

func Client(r *http.Request, trusted []netip.Prefix) (ip *netip.Addr, userAgent string)

Client returns the real client's IP address and user agent.

If the request comes from a trusted proxy, X-Forwarded-For is read from the right, skipping trusted addresses, and the first untrusted one is the client: entries further left were written by the client itself and can't be believed. X-Forwarded-User-Agent is used if present. Requests from anywhere else use the connection's own address and User-Agent. ip is nil if no address can be determined.

func Decode

func Decode(w http.ResponseWriter, r *http.Request, dst any) error

Decode reads a single JSON object from r's body into dst. Unknown fields and trailing data are rejected, so typos fail loudly instead of being ignored.

func RequestIDFrom

func RequestIDFrom(ctx context.Context) string

RequestIDFrom returns the request ID set by WithRequestID, or "".

func WithRequestID

func WithRequestID(h http.Handler) http.Handler

WithRequestID wraps h so every request has an ID, available through RequestIDFrom and returned in the X-Request-ID response header. It reuses an ID already set on the response by the project's own middleware, then a well-formed incoming X-Request-ID, and otherwise generates a UUIDv7.

func WriteDecodeError

func WriteDecodeError(w http.ResponseWriter, r *http.Request, err error)

WriteDecodeError writes the response for an error from Decode.

func WriteError

func WriteError(w http.ResponseWriter, r *http.Request, status int, code, message string, details []FieldError)

WriteError writes an error in the standard format. message must be safe to show to users.

func WriteInternalError

func WriteInternalError(w http.ResponseWriter, r *http.Request, log *slog.Logger, err error)

WriteInternalError logs err and writes a generic 500. The client never sees err, which may contain internal details.

func WriteJSON

func WriteJSON(w http.ResponseWriter, r *http.Request, status int, v any)

WriteJSON writes v as a JSON response.

Types

type FieldError

type FieldError struct {
	Field   string `json:"field"`
	Code    string `json:"code"`
	Message string `json:"message"`
}

FieldError describes one invalid field in a validation_failed error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL