API Reference
A map of the public surface. Each entry links to the page that explains it in context.
Package ezz
App
func New() *App
| Method | Purpose |
|---|---|
Logger(*slog.Logger) *App | Set the logger and rebuild the default middleware |
Auth(AuthProvider) *App | Register the authentication provider |
DefaultAuth(AuthRule) *App | Change the default rule; nil makes routes public |
Use(...Middleware) *App | Append middleware |
GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS(pattern, http.Handler) *RouteBuilder | Register a route |
Handle(method, pattern string, h http.Handler) *RouteBuilder | Register with an explicit method |
Group(prefix string) *RouteGroup | Create a route group |
ServeHTTP(w, r) | Satisfies http.Handler |
Listen(addr string) error | Start a server on addr |
Routes() []*Route | Registered routes |
GetRoutes() []RouteInfo | Legacy view used by the OpenAPI generator |
type AuthProvider interface {
Authenticate(r *http.Request) (any, error)
}
func UserFromContext(ctx context.Context) any
See Routing and Auth overview.
RouteGroup
| Method | Purpose |
|---|---|
Use(...Middleware) *RouteGroup | Middleware for routes in this group |
Auth(AuthRule) *RouteGroup | Auth rule for routes in this group |
Group(prefix string) *RouteGroup | Nested group, inheriting middleware and rule |
GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS(pattern, h) *RouteBuilder | Register a route under the prefix |
Route and RouteBuilder
type Route struct {
Method, Pattern string
Handler http.Handler
AuthRule AuthRule
Summary string
Description string
Tags []string
OperationID string
Deprecated bool
RequestType reflect.Type
ResponseType reflect.Type
Responses map[int]ResponseInfo
}
type ResponseInfo struct {
Description string
Type reflect.Type
Example any
}
*RouteBuilder method | Effect |
|---|---|
Auth(AuthRule) | Set the route's rule |
Public() | Allow unauthenticated access |
Summary(string) | Store a summary |
Description(string) | Set the OpenAPI description |
Tags(...string) | Set OpenAPI tags |
OperationID(string) | Store an operation ID |
Deprecated() | Mark deprecated |
Response(status int, description string, example ...any) | Record a response |
Tags and description are what the generator currently emits; see OpenAPI.
Auth rules
type AuthRule interface {
Check(user any) error
IsPublic() bool
}
type RoleChecker interface { HasRole(role string) bool }
type PermissionChecker interface { HasPermission(permission string) bool }
| Constructor | Requires |
|---|---|
Public() AuthRule | Nothing |
Authenticated() AuthRule | A non-nil user |
Role(role string) AuthRule | That role |
AnyRole(roles ...string) AuthRule | Any listed role |
AllRoles(roles ...string) AuthRule | Every listed role |
Permission(perm string) AuthRule | That permission |
Custom(fn func(user any) bool) AuthRule | The predicate to pass |
var ErrUnauthorized = NewHTTPError(http.StatusUnauthorized, "Unauthorized")
var ErrForbidden = NewHTTPError(http.StatusForbidden, "Forbidden")
auth package. auth.Role(...) returns an auth.AuthRule struct from an earlier design, which does not satisfy ezz.AuthRule and cannot be passed to .Auth(...).See Auth rules.
Handlers
func H[Req, Resp any](fn func(*Context, Req) (Resp, error)) *Handler[Req, Resp]
func HFunc[Resp any](fn func(*Context) (Resp, error)) *Handler[struct{}, Resp]
type TypedHandler interface {
http.Handler
RequestType() reflect.Type
ResponseType() reflect.Type
}
See Handlers.
Errors
type HTTPError struct {
StatusCode int
Message string
Internal error
}
func NewHTTPError(status int, message string) *HTTPError
func (e *HTTPError) WithInternal(err error) *HTTPError
Constructors: BadRequest, Unauthorized, Forbidden, NotFound, Conflict, UnprocessableEntity, InternalServerError. See Errors.
Context
type Context struct {
context.Context
Request *http.Request
Response http.ResponseWriter
StartTime time.Time
}
| Group | Methods |
|---|---|
| Metadata | GetRequestID, GetClientIP, GetUserAgent, GetTraceID |
| Request | Param, SetParam, Query, QueryValues, QueryAll, RequestHeader, Body |
| Response | JSON, Error, Status, SetHeader, NoContent, Redirect, ServeFile, Stream |
| State | Written, StatusCode, User, MustUser, SetUser |
type StreamWriter struct{}
func (sw *StreamWriter) WriteEvent(eventType, data string) error
func (sw *StreamWriter) WriteJSON(eventType string, data any) error
func (sw *StreamWriter) Write(data []byte) (int, error)
func (sw *StreamWriter) Flush()
func (sw *StreamWriter) Close() error
See Context.
Middleware
type Middleware func(http.Handler) http.Handler
func Logging(logger *slog.Logger) Middleware
func Recovery(logger *slog.Logger) Middleware
func RequestID() Middleware
func CORS(config CORSConfig) Middleware
func DefaultCORSConfig() CORSConfig
type CORSConfig struct {
AllowedOrigins []string
AllowedMethods []string
AllowedHeaders []string
AllowCredentials bool
MaxAge int
}
See Middleware.
Testing helpers
func NewTestApp() *TestApp
func NewTestContext(w http.ResponseWriter, r *http.Request) *Context
func MockHandler[Req, Resp any](fn func(*Context, Req) (Resp, error)) *Handler[Req, Resp]
func WithJWT(token string) map[string]string
func WithHeaders(headers map[string]string) map[string]string
func WithContentType(contentType string) map[string]string
*TestApp: App, GET, POST, PUT, PATCH, DELETE, Request.
*TestResponse: StatusCode, Header, BodyString, JSON, AssertStatus, AssertHeader, AssertBodyContains, AssertJSON.
See Testing.
Package ezz/binding
func Bind(r *http.Request, target any) error
func BindJSON(r *http.Request, target any) error
func BindQuery(values url.Values, target any) error
func BindPath(r *http.Request, target any) error
func Validate(target any) error
func NewBinder(typ reflect.Type) *Binder
func (b *Binder) Bind(r *http.Request, target any) error
func NewValidator(typ reflect.Type) *Validator
func (v *Validator) Validate(target any) error
type ValidationError struct {
Field string
Tag string
Value any
Message string
}
type ValidationErrors []ValidationError
Tags: path, query, header, form, json, default, validate, description, example. See Request binding and Validation.
Package ezz/middleware
func Gzip(config ...CompressionConfig) ezz.Middleware
func DecompressionMiddleware() ezz.Middleware
func DefaultCompressionConfig() CompressionConfig
type CompressionConfig struct {
Level int
MinLength int
MIMETypes map[string]bool
}
type RateLimiter interface {
Allow(key string) bool
Reset(key string)
}
func NewBucketLimiter(capacity int, rate time.Duration) *BucketLimiter
func NewMemoryLimiter(capacity int, rate, cleanup time.Duration) *MemoryLimiter
func RateLimitMiddleware(limiter RateLimiter, keyFunc func(*http.Request) string) ezz.Middleware
func IPRateLimit(requestsPerMinute int) ezz.Middleware
func UserRateLimitMiddleware(requestsPerMinute int, userIDFunc func(*http.Request) string) ezz.Middleware
func APIKeyRateLimitMiddleware(requestsPerMinute int) ezz.Middleware
func CustomRateLimitMiddleware(capacity int, refillRate time.Duration, keyFunc func(*http.Request) string) ezz.Middleware
See Middleware.
Package ezz/openapi
func NewGenerator() *Generator
func (g *Generator) GenerateFromApp(app *ezz.App) *Spec
func MustJSON(spec *Spec) string
func ServeScalar(app *ezz.App, specPath, docsPath string, config ...ScalarConfig)
func SetupDocsEndpoints(app *ezz.App, config ...ScalarConfig)
func DefaultScalarConfig() ScalarConfig
func AddSecurityScheme(generator *Generator, name string, scheme SecurityScheme)
func ApplyScalarOptions(config *ScalarConfig, options ...func(*ScalarConfig))
func WithCustomTheme(theme string) func(*ScalarConfig)
func WithDarkMode(enabled bool) func(*ScalarConfig)
func WithLayout(layout string) func(*ScalarConfig)
Spec types: Spec, Info, Contact, License, Server, ServerVariable, PathItem, Operation, Parameter, RequestBody, Response, Header, MediaType, ExampleValue, Schema, Components, SecurityScheme, OAuthFlows, OAuthFlow, SecurityRequirement.
type ScalarConfig struct {
Title string
Theme string
Layout string
DarkMode bool
HideModels bool
ShowSidebar bool
CustomCSS string
FavIcon string
}
Package ezz/auth
Providers and claims
type JWTProvider interface {
ValidateToken(token string) (*Claims, error)
GenerateToken(claims *Claims) (string, error)
}
type Claims struct {
Subject, Issuer, Audience, ID string
ExpiresAt, IssuedAt, NotBefore int64
Custom map[string]any
}
func (c *Claims) Valid() error
func NewHMACProvider(secret, issuer string) *HMACProvider
func NewGoTrueProvider(serverURL, jwtSecret string) *GoTrueProvider
func (g *GoTrueProvider) GetUser(token string) (*GoTrueUser, error)
func NewJWTAuthProvider(provider JWTProvider) *JWTAuthProvider
func (p *JWTAuthProvider) WithResolver(AuthorizationResolver) *JWTAuthProvider
func (p *JWTAuthProvider) WithAuditLogger(AuditLogger) *JWTAuthProvider
func (p *JWTAuthProvider) Authenticate(r *http.Request) (any, error)
WithRoleExtractor and WithPermissionChecker exist but are not consulted during authentication. See JWT providers.
Users
type User interface {
ID() string
GetClaims() *Claims
GetAttribute(key string) (any, bool)
}
func NewBasicUser(claims *Claims) *BasicUser
func (u *BasicUser) HasRole(role string) bool
func NewAuthorizedUser(ctx context.Context, claims *Claims, resolver AuthorizationResolver) *AuthorizedUser
func (u *AuthorizedUser) HasRole(role string) bool
func (u *AuthorizedUser) HasPermission(permission string) bool
func (u *AuthorizedUser) AuthzError() error
func UserFromContext(ctx context.Context) User
Authorization
type AuthorizationResolver interface {
Resolve(ctx context.Context, user User) (Authorization, error)
}
type Authorization struct {
Roles []string
Permissions []string
}
func ClaimRoles(claims *Claims) []string
func Cached(inner AuthorizationResolver, ttl time.Duration) *CachedResolver
func (c *CachedResolver) Invalidate(userID string)
func (c *CachedResolver) InvalidateAll()
Role hierarchies
func BuildHierarchy() *HierarchyBuilder
func NewHierarchy() *Hierarchy
func NewCommonRoleHierarchy() *Hierarchy
func DefaultWebAppHierarchy() *Hierarchy
func (h *Hierarchy) GetImpliedRoles(role string) []string
func (h *Hierarchy) AddRoleImplication(parent, child string)
func (h *Hierarchy) RemoveRoleImplication(parent, child string)
func (h *Hierarchy) HasImplication(parent, child string) bool
Builder methods: Role, Admin, User, Moderator, Implies, ImpliesAll, Build.
Audit
type AuditLogger interface {
LogAuthEvent(ctx context.Context, event AuditEvent)
LogLoginAttempt(ctx context.Context, userID, result string, details map[string]any)
LogAccessAttempt(ctx context.Context, userID, resource, action, result string, details map[string]any)
LogRoleCheck(ctx context.Context, userID, role, result string, details map[string]any)
LogPermissionCheck(ctx context.Context, userID, permission, result string, details map[string]any)
}
func NewSlogAuditLogger(logger *slog.Logger) *SlogAuditLogger
func NewNoOpAuditLogger() *NoOpAuditLogger
See Audit logging.
GoTrue
func NewGoTrue(cfg GoTrueConfig) *GoTrue
func (gt *GoTrue) AuthProvider() *JWTAuthProvider
func (gt *GoTrue) Mount(app *ezz.App, prefix string)
type GoTrueConfig struct {
InternalURL string
JWTSecret string
AuditLogger AuditLogger
RateLimiter RateLimiter
ServerHeaders map[string]string
HTTPClient *http.Client
TrustedProxies []string
}
type RateLimiter interface {
Allow(ctx context.Context, key string) (bool, error)
}
Endpoint types: HealthResponse, SettingsResponse, SignupRequest, TokenRequest, UserObject, SessionResponse, OTPRequest, VerifyRequest, RecoverRequest, ResendRequest, MessageResponse, UpdateUserRequest, ReauthenticateRequest, OAuthServerMetadata, JWKSResponse, OAuthTokenRequest, OAuthTokenResponse, ClientRegistrationRequest, ClientRegistrationResponse, OAuthUserInfo, and the Passkey* types.
See GoTrue proxy and Endpoints.
Middleware and context helpers
func JWTMiddleware(provider JWTProvider) ezz.Middleware
func OptionalJWTMiddleware(provider JWTProvider) ezz.Middleware
func GetClaims(ctx context.Context) *Claims
func GetUserID(ctx context.Context) string
func BatchValidateTokens(provider JWTProvider, tokens []string) ([]*Claims, []error)
Extractors, checkers, and caches
Building blocks from the pre-resolver design. They are still exported and useful inside your own resolver, but the app does not call them.
type RoleExtractor interface {
ExtractRoles(ctx context.Context, user User) ([]string, error)
HasRole(ctx context.Context, user User, role string) (bool, error)
}
type PermissionChecker interface {
HasPermission(ctx context.Context, user User, permission string) (bool, error)
GetPermissions(ctx context.Context, user User) ([]string, error)
}
Implementations: ClaimsExtractor, GoTrueExtractor, CompositeExtractor, StaticExtractor, HierarchyExtractor, RolePermissionChecker, CachedExtractor, CachedChecker.
Caching primitives: Cache, NewLRUCache, CacheConfig, DefaultCacheConfig, CacheManager, OptimizedCacheConfig, CacheStats.
Legacy configuration: AuthConfig (aliased as Config) with ToAuthProvider(), AuthRule with Public, Authenticated, Role, AnyRole, AllRoles, RequirePermission, JWTConfig, DefaultJWTConfig, RequestCache, GetRequestCache.
Package ezz/auth/ratelimit
func NewRedis(client redis.UniversalClient, limit int, window time.Duration) *Redis
func (r *Redis) Allow(ctx context.Context, key string) (bool, error)
A fixed-window counter satisfying auth.RateLimiter. See Client IP and rate limits.