Documentation
¶
Overview ¶
Package router provides a lightweight, JSON-centric wrapper around Go's native http.ServeMux.
It simplifies building JSON APIs by offering a consolidated "Exchange" object for handling requests and responses, standardized error formatting, and a middleware chaining mechanism.
Basic Usage:
// 1. Setup the router with options
logger := log.New()
r := router.New(
router.WithLogger(logger),
router.WithMiddleware(middleware.Log(logger)),
)
// 2. Define a handler
// You can use a closure, or a struct that satisfies the Handler interface.
r.HandleFunc("POST /users", func(e *router.Exchange) error {
var req CreateUserRequest
// BindJSON enforces Content-Type and parses the body.
// It returns a specific *router.Error type if validation fails.
if err := e.BindJSON(&req); err != nil {
return err
}
// ... Logic to save user ...
// Return JSON response
return e.JSON(http.StatusCreated, UserResponse{ID: "123"})
})
// 3. Start the server
http.ListenAndServe(":8080", r)
Index ¶
- Constants
- type Error
- type Exchange
- func (e *Exchange) BindJSON(v any) *Error
- func (e *Exchange) Context() context.Context
- func (e *Exchange) Form(code int, v url.Values) error
- func (e *Exchange) GetHeader(key string) string
- func (e *Exchange) Header() http.Header
- func (e *Exchange) JSON(code int, v any) error
- func (e *Exchange) Method() string
- func (e *Exchange) Param(name string) string
- func (e *Exchange) Path() string
- func (e *Exchange) Query() url.Values
- func (e *Exchange) ReadForm() (url.Values, *Error)
- func (e *Exchange) Redirect(url string, code int) error
- func (e *Exchange) RedirectTo(base string, params url.Values, code int) error
- func (e *Exchange) SetHeader(key, value string)
- func (e *Exchange) Status(code int)
- func (e *Exchange) URL() *url.URL
- type Handler
- type HandlerFunc
- type Option
- type Router
- func (r *Router) Handle(pattern string, handler Handler, mws ...middleware.Pipe)
- func (r *Router) HandleFunc(pattern string, fn func(*Exchange) error, mws ...middleware.Pipe)
- func (r *Router) Mount(pattern string, handler http.Handler)
- func (r *Router) ServeHTTP(res http.ResponseWriter, req *http.Request)
Constants ¶
const ( // ReasonWrongType indicates that the request had an unsupported content type. ReasonWrongType = "wrong_type" // ReasonEmptyBody indicates that the request body was empty. ReasonEmptyBody = "empty_body" // ReasonParseJSON indicates that there was an error parsing the JSON body. ReasonParseJSON = "parse_json" // ReasonParseForm indicates that there was an error parsing form data. ReasonParseForm = "parse_form" // ReasonServerError indicates that an unexpected internal error occurred. ReasonServerError = "server_error" )
Standard error reasons used for machine-readable error codes.
const ( // MediaTypeJSON is the media type for JSON content. MediaTypeJSON = "application/json" // MediaTypeForm is the media type for URL-encoded form data. MediaTypeForm = "application/x-www-form-urlencoded" )
Standard media types used in the Content-Type header.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Error ¶
type Error struct {
// Status is the HTTP status code (e.g., 400, 404, 500).
Status int `json:"status"`
// Reason is a short string identifying the error type (e.g.,
// "invalid_input").
Reason string `json:"reason"`
// Description is a human-readable explanation of the error cause.
Description string `json:"description"`
// ID is a unique identifier of the specific occurrence for tracing purposes
// (optional).
ID string `json:"id,omitempty"`
// Cause is the underlying error that triggered this error (if any).
// It is excluded from JSON serialization to prevent leaking internal details.
Cause error `json:"-"`
}
Error describes the standardized shape of API errors returned to clients.
Handlers can return this struct directly to control the HTTP status code and error details. If a handler returns a standard Go error, the Router will wrap it in a generic internal server error.
type Exchange ¶
type Exchange struct {
// R is the incoming HTTP request.
R *http.Request
// W is a writer for the outgoing HTTP response.
W http.ResponseWriter
}
Exchange acts as a context object for a single HTTP request/response cycle.
It wraps the underlying *http.Request and http.ResponseWriter to provide convenient helper methods for common API tasks, such as parsing JSON, reading parameters, and writing structured responses.
func (*Exchange) BindJSON ¶
BindJSON decodes the request body into v.
This method enforces strict API hygiene: 1. It verifies that the media type is "application/json". 2. It checks that the payload is not empty. 3. It unmarshals the JSON.
If any of these checks fail, it returns a structured error that handlers can return directly.
func (*Exchange) Context ¶
Context returns the request's context. This is commonly used for cancellation signals and request scoping.
func (*Exchange) Form ¶ added in v1.1.0
Form writes the values as URL-encoded form data with the given status code.
It automatically sets the Content-Type header to MediaTypeForm if it has not already been set. When encoding fails, an error is returned.
func (*Exchange) JSON ¶
JSON encodes v as JSON and writes it to the response with the given HTTP status code.
It automatically sets the Content-Type header to MediaTypeJSON if it has not already been set. When encoding fails, an error is returned.
func (*Exchange) Param ¶
Param retrieves a path parameter by name.
This relies on the routing pattern (e.g., "GET /users/{id}"). If the parameter does not exist, it returns an empty string.
func (*Exchange) Query ¶
Query parses the URL query parameters of the request. Malformed pairs will be silently discarded.
func (*Exchange) ReadForm ¶ added in v1.1.0
ReadForm parses the request body as URL-encoded form data and returns the values.
Unlike the standard http.Request.FormValue(), this strictly accesses the PostForm (body) only, ignoring URL query parameters. This is crucial for security protocols like OAuth to prevent query parameter injection.
func (*Exchange) Redirect ¶
Redirect replies to the request with a redirect to url, which may be a path relative to the request path.
Any non-ASCII characters in url will be percent-encoded, but existing percent encodings will not be changed. The provided code should be in the 3xx range.
func (*Exchange) RedirectTo ¶ added in v1.1.0
RedirectTo constructs a URL by merging the base URL with the provided query parameters and redirects the client.
This is particularly useful for callbacks.
type Handler ¶
type Handler interface {
// ServeHTTP processes an HTTP request encapsulated in the Exchange object.
ServeHTTP(e *Exchange) error
}
Handler defines the interface for HTTP request handlers used by the Router.
This interface allows using struct-based handlers (useful for dependency injection) in addition to simple functions.
type HandlerFunc ¶
HandlerFunc defines the function signature for HTTP request handlers.
func (HandlerFunc) ServeHTTP ¶
func (f HandlerFunc) ServeHTTP(e *Exchange) error
ServeHTTP satisfies the Handler interface, allowing HandlerFunc to be used wherever a Handler is expected.
type Option ¶
type Option func(*Router)
Option defines a functional configuration option for the Router.
func WithLogger ¶
WithLogger sets a custom logger for the Router. If not set, the Router defaults to using slog.Default(). A nil value will be ignored.
func WithMiddleware ¶
func WithMiddleware(pipes ...middleware.Pipe) Option
WithMiddleware adds global middleware pipes to the Router. These pipes are applied to every route registered with the Router.
type Router ¶
type Router struct {
// Mux is the underlying http.ServeMux. It is exposed to allow direct
// usage with http.ListenAndServe.
Mux *http.ServeMux
// contains filtered or unexported fields
}
Router represents an HTTP request router with middleware support.
func (*Router) Handle ¶
func (r *Router) Handle( pattern string, handler Handler, mws ...middleware.Pipe, )
Handle registers a new route with the given pattern, handler, and optional middleware pipes.
The pattern string must follow Go 1.22+ syntax (e.g., "GET /users/{id}").
The handler is wrapped with the Router's global middleware and any local middleware provided for this specific route.
func (*Router) HandleFunc ¶
HandleFunc is a convenience wrapper for Handle that accepts a function instead of a Handler interface.