Documentation
¶
Overview ¶
Package router wraps http.ServeMux with OpenAPI validation, CORS, timeouts, and logging defaults. ExampleNew_customOptions demonstrates how to combine built-in and custom middlewares.
Index ¶
- func New(apiHandle http.Handler, opts ...Option) *http.ServeMux
- type CORSConfig
- type Config
- type Middleware
- type Option
- func WithConfig(cfg Config) Option
- func WithConfigMutator(mutator func(*Config)) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMiddlewareChain(middlewares ...Middleware) Option
- func WithMiddlewares(middlewares ...Middleware) Option
- func WithSwagger(swagger *openapi3.T) Option
- func WithTrailingMiddlewares(middlewares ...Middleware) Option
- func WithoutCORSMiddleware() Option
- func WithoutLoggingMiddleware() Option
- func WithoutOpenAPIValidation() Option
- func WithoutTimeoutMiddleware() Option
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func New ¶
New returns a new *http.ServeMux configured with the provided handler and options.
Example (CustomOptions) ¶
package main
import (
"fmt"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"strings"
"time"
"github.com/drblury/apiweaver/router"
)
func main() {
apiHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "hello")
})
mux := router.New(
apiHandler,
router.WithLogger(slog.New(slog.NewJSONHandler(io.Discard, nil))),
router.WithConfig(router.Config{
Timeout: 2 * time.Second,
CORS: router.CORSConfig{
Origins: []string{"https://example.com"},
Methods: []string{http.MethodGet, http.MethodOptions},
Headers: []string{"Content-Type"},
},
HideHeaders: []string{"Authorization"},
}),
router.WithMiddlewares(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Stage", "prepend")
next.ServeHTTP(w, r)
})
}),
router.WithTrailingMiddlewares(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
w.Header().Set("X-Chain", "completed")
})
}),
)
req := httptest.NewRequest(http.MethodGet, "/", nil)
req.Header.Set("Origin", "https://example.com")
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
fmt.Println(rec.Header().Get("Access-Control-Allow-Origin"))
fmt.Println(rec.Header().Get("X-Stage"))
fmt.Println(rec.Header().Get("X-Chain"))
fmt.Println(strings.TrimSpace(rec.Body.String()))
}
Output: https://example.com prepend completed hello
Types ¶
type CORSConfig ¶
CORSConfig configures CORS.
type Config ¶
type Config struct {
Timeout time.Duration
CORS CORSConfig
QuietdownRoutes []string
HideHeaders []string
}
Config configures the router.
type Middleware ¶
Middleware wraps an http.Handler to produce a new http.Handler.
type Option ¶
type Option func(*options)
Option configures the router via the functional options pattern.
func WithConfig ¶
WithConfig replaces the router configuration with the provided value.
func WithConfigMutator ¶
WithConfigMutator applies a mutation to the router configuration after defaults are set.
func WithLogger ¶
WithLogger provides the structured logger to be used by the logging middleware.
func WithMiddlewareChain ¶
func WithMiddlewareChain(middlewares ...Middleware) Option
WithMiddlewareChain fully overrides the middleware chain with the provided sequence.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/drblury/apiweaver/router"
)
func main() {
records := make([]string, 0, 4)
middleware := func(label string) router.Middleware {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
records = append(records, label+"-before")
next.ServeHTTP(w, r)
records = append(records, label+"-after")
})
}
}
mux := router.New(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "ok")
}),
router.WithMiddlewareChain(
middleware("first"),
middleware("second"),
),
)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
fmt.Println(rec.Code)
fmt.Println(records)
}
Output: 200 [first-before second-before second-after first-after]
func WithMiddlewares ¶
func WithMiddlewares(middlewares ...Middleware) Option
WithMiddlewares prepends custom middlewares ahead of the default chain.
func WithSwagger ¶
WithSwagger wires the OpenAPI document for request validation.
func WithTrailingMiddlewares ¶
func WithTrailingMiddlewares(middlewares ...Middleware) Option
WithTrailingMiddlewares appends middlewares after the default chain.
func WithoutCORSMiddleware ¶
func WithoutCORSMiddleware() Option
WithoutCORSMiddleware disables the CORS middleware regardless of configuration.
func WithoutLoggingMiddleware ¶
func WithoutLoggingMiddleware() Option
WithoutLoggingMiddleware disables the logging middleware.
func WithoutOpenAPIValidation ¶
func WithoutOpenAPIValidation() Option
WithoutOpenAPIValidation disables the OpenAPI validation middleware.
func WithoutTimeoutMiddleware ¶
func WithoutTimeoutMiddleware() Option
WithoutTimeoutMiddleware disables the timeout middleware.