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) 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) Redirect(url string, code int) error
- func (e *Exchange) SetHeader(key, value string)
- func (e *Exchange) Status(code int) error
- 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" // ReasonServerError indicates that an unexpected internal error occurred. ReasonServerError = "server_error" )
Standard error reasons used for machine-readable error codes.
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) JSON ¶
JSON encodes v as JSON and writes it to the response with the given HTTP status code.
It automatically sets the "Content-Type: application/json" header. If 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) 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.
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.