route

package
v0.15.1 Latest Latest
Warning

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

Go to latest
Published: Mar 24, 2026 License: Apache-2.0 Imports: 8 Imported by: 1

Documentation

Overview

Package route provides route definition, grouping, and mounting functionality for the Rivaas router.

This package contains:

  • Route: Represents a registered route with constraints and metadata
  • Group: Route grouping with shared prefix and middleware
  • Mount: Subrouter mounting functionality
  • Constraints: Parameter validation (int, UUID, regex, enum, etc.)

The types in this package are used at application startup during route registration and do not affect runtime request handling performance.

Route Definition

Routes are created through the Router's HTTP method functions:

r.GET("/users/:id", handler).WhereInt("id")
r.POST("/users", handler).SetName("users.create")

Route Groups

Groups allow organizing routes under a common prefix with shared middleware:

api := r.Group("/api/v1", authMiddleware)
api.GET("/users", listUsers)
api.GET("/users/:id", getUser)

Mounting Subrouters

Subrouters can be mounted at a prefix, preserving route patterns for observability:

admin := router.MustNew()
admin.GET("/users", adminListUsers)

r.Mount("/admin", admin, route.InheritMiddleware())

Startup Operations

All operations in this package occur at startup time during route registration. The use of interfaces allows the router package to call these functions without creating import cycles.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CompilerConstraints

func CompilerConstraints(constraints []Constraint) []compiler.RouteConstraint

CompilerConstraints converts constraints to compiler-compatible format.

func CompilerHandlers

func CompilerHandlers(handlers []Handler) []compiler.HandlerFunc

CompilerHandlers converts handlers to compiler-compatible format.

func ExtractConstraintPattern

func ExtractConstraintPattern(c Constraint) string

ExtractConstraintPattern extracts the pattern string from a compiled constraint.

Types

type Constraint

type Constraint struct {
	Param   string         // Parameter name
	Pattern *regexp.Regexp // Compiled regex pattern
}

Constraint represents a compiled constraint for route parameters. Constraints are compiled for validation during routing.

func ConstraintFromPattern

func ConstraintFromPattern(param, pattern string) Constraint

ConstraintFromPattern creates a Constraint from a parameter name and regex pattern. Panics if the pattern is invalid (by design for early error detection).

Example

ExampleConstraintFromPattern demonstrates creating a constraint from a regex pattern.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	constraint := route.ConstraintFromPattern("id", `\d+`)

	fmt.Println("Param:", constraint.Param)
	fmt.Println("Matches '123':", constraint.Pattern.MatchString("123"))
	fmt.Println("Matches 'abc':", constraint.Pattern.MatchString("abc"))
}
Output:
Param: id
Matches '123': true
Matches 'abc': false

type ConstraintKind

type ConstraintKind uint8

ConstraintKind represents the type of constraint applied to a route parameter.

const (
	ConstraintNone ConstraintKind = iota
	ConstraintInt
	ConstraintFloat
	ConstraintUUID
	ConstraintRegex
	ConstraintEnum
	ConstraintDate     // RFC3339 full-date
	ConstraintDateTime // RFC3339 date-time
)

type DiagnosticKind

type DiagnosticKind string

DiagnosticKind categorizes diagnostic events.

const (
	// DiagHighParamCount indicates a route has more than 8 parameters.
	DiagHighParamCount DiagnosticKind = "route_param_count_high"
)

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group represents a route group that allows organizing related routes under a common path prefix with shared middleware. Groups enable hierarchical organization of API endpoints and middleware application.

Groups inherit the parent router's global middleware and can add their own group-specific middleware. The final handler chain for a grouped route will be: [global middleware...] + [group middleware...] + [route handlers...]

Example:

api := r.Group("/api/v1", AuthMiddleware())
users := api.Group("/users", RateLimitMiddleware())
users.GET("/:id", getUserHandler) // Final path: /api/v1/users/:id

func NewGroup

func NewGroup(registrar Registrar, prefix string, middleware []Handler) *Group

NewGroup creates a new Group with the given registrar, prefix, and middleware.

func (*Group) DELETE

func (g *Group) DELETE(path string, handlers ...Handler) *Route

DELETE adds a DELETE route to the group with the group's prefix. The final route path will be the group prefix + the provided path.

Example:

api := r.Group("/api/v1")
api.DELETE("/users/:id", handler) // Final path: /api/v1/users/:id

func (*Group) GET

func (g *Group) GET(path string, handlers ...Handler) *Route

GET adds a GET route to the group with the group's prefix. The final route path will be the group prefix + the provided path.

Example:

api := r.Group("/api/v1")
api.GET("/users", handler) // Final path: /api/v1/users

func (*Group) Group

func (g *Group) Group(prefix string, middleware ...Handler) *Group

Group creates a nested route group under the current group. The new group's prefix will be the parent's prefix + the provided prefix. Middleware and name prefix from the parent group are inherited by the nested group.

Example:

api := r.Group("/api")
v1 := api.Group("/v1")  // Creates /api/v1 prefix
v1.GET("/users", handler)  // Matches /api/v1/users

func (*Group) HEAD

func (g *Group) HEAD(path string, handlers ...Handler) *Route

HEAD adds a HEAD route to the group with the group's prefix. The final route path will be the group prefix + the provided path.

Example:

api := r.Group("/api/v1")
api.HEAD("/users/:id", handler) // Final path: /api/v1/users/:id

func (*Group) Handle added in v0.15.0

func (g *Group) Handle(method, path string, handlers ...Handler) *Route

Handle registers a route for the given HTTP method and path. It is used by the app package to centralize the method switch. Supported methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS. Panics with a clear message for unsupported methods.

func (*Group) NamePrefix

func (g *Group) NamePrefix() string

NamePrefix returns the current name prefix for this group.

func (*Group) OPTIONS

func (g *Group) OPTIONS(path string, handlers ...Handler) *Route

OPTIONS adds an OPTIONS route to the group with the group's prefix. The final route path will be the group prefix + the provided path.

Example:

api := r.Group("/api/v1")
api.OPTIONS("/users", handler) // Final path: /api/v1/users

func (*Group) PATCH

func (g *Group) PATCH(path string, handlers ...Handler) *Route

PATCH adds a PATCH route to the group with the group's prefix. The final route path will be the group prefix + the provided path.

Example:

api := r.Group("/api/v1")
api.PATCH("/users/:id", handler) // Final path: /api/v1/users/:id

func (*Group) POST

func (g *Group) POST(path string, handlers ...Handler) *Route

POST adds a POST route to the group with the group's prefix. The final route path will be the group prefix + the provided path.

Example:

api := r.Group("/api/v1")
api.POST("/users", handler) // Final path: /api/v1/users

func (*Group) PUT

func (g *Group) PUT(path string, handlers ...Handler) *Route

PUT adds a PUT route to the group with the group's prefix. The final route path will be the group prefix + the provided path.

Example:

api := r.Group("/api/v1")
api.PUT("/users/:id", handler) // Final path: /api/v1/users/:id

func (*Group) SetNamePrefix

func (g *Group) SetNamePrefix(prefix string) *Group

SetNamePrefix sets a prefix for all route names in this group. The prefix is appended to any existing name prefix from parent groups, enabling hierarchical route naming. Returns the group for method chaining.

Example:

api := r.Group("/api").SetNamePrefix("api.")
v1 := api.Group("/v1").SetNamePrefix("v1.")  // Inherits "api." prefix
v1.GET("/users", handler).SetName("users.list")
// Full route name becomes: "api.v1.users.list"

func (*Group) Use

func (g *Group) Use(middleware ...Handler)

Use adds middleware to the group that will be executed for all routes in this group. Group middleware is executed after the router's global middleware but before the route-specific handlers.

Example:

api := r.Group("/api")
api.Use(AuthMiddleware(), LoggingMiddleware())
api.GET("/users", getUsersHandler) // Will execute auth + logging + handler

type Handler

type Handler = any

Handler is a type alias for handler functions. In practice, this will be router.HandlerFunc (func(*Context)). Using any here avoids the import cycle with the main router package.

type Info

type Info struct {
	Method      string            // HTTP method (GET, POST, etc.)
	Path        string            // Route path pattern (/users/:id)
	HandlerName string            // Name of the handler function
	Middleware  []string          // Middleware chain names (in execution order)
	Constraints map[string]string // Parameter constraints (param -> regex pattern)
	IsStatic    bool              // True if route has no dynamic parameters
	Version     string            // API version (e.g., "v1", "v2"), empty if not versioned
	ParamCount  int               // Number of URL parameters in this route
}

Info contains comprehensive information about a registered route for introspection. This is used for debugging, documentation generation, API documentation, and monitoring.

Enhanced fields provide deep insights into route configuration:

  • Middleware: Full middleware chain for this route
  • Constraints: Parameter validation rules
  • IsStatic: Whether the route is static
  • Version: API versioning information

type MountConfig

type MountConfig struct {
	InheritMiddleware bool
	ExtraMiddleware   []Handler
	NamePrefix        string
	NotFoundHandler   Handler
}

MountConfig holds configuration for a mounted subrouter.

func BuildMountConfig

func BuildMountConfig(opts ...MountOption) *MountConfig

BuildMountConfig applies mount options and returns the configuration.

Example

ExampleBuildMountConfig demonstrates building mount configuration with multiple options.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	cfg := route.BuildMountConfig(
		route.InheritMiddleware(),
		route.NamePrefix("admin."),
	)

	fmt.Println("InheritMiddleware:", cfg.InheritMiddleware)
	fmt.Println("NamePrefix:", cfg.NamePrefix)
}
Output:
InheritMiddleware: true
NamePrefix: admin.

type MountOption

type MountOption func(*MountConfig)

MountOption configures how a subrouter is mounted.

func InheritMiddleware

func InheritMiddleware() MountOption

InheritMiddleware makes the subrouter inherit parent router's global middleware. Parent middleware runs before subrouter middleware.

Example

ExampleInheritMiddleware demonstrates the InheritMiddleware mount option.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	opt := route.InheritMiddleware()
	cfg := &route.MountConfig{}
	opt(cfg)

	fmt.Println("InheritMiddleware:", cfg.InheritMiddleware)
}
Output:
InheritMiddleware: true

func NamePrefix

func NamePrefix(prefix string) MountOption

NamePrefix adds a prefix to all route names in the subrouter. Useful for metrics and logging scoping.

Example:

r.Mount("/admin", sub, route.NamePrefix("admin."))
// Route named "users" becomes "admin.users"
Example

ExampleNamePrefix demonstrates the NamePrefix mount option.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	cfg := route.BuildMountConfig(
		route.NamePrefix("api.v1."),
	)

	fmt.Println("NamePrefix:", cfg.NamePrefix)
}
Output:
NamePrefix: api.v1.

func WithMiddleware

func WithMiddleware(m ...Handler) MountOption

WithMiddleware adds additional middleware to the subrouter. These middleware run after inherited middleware but before route handlers.

Example

ExampleWithMiddleware demonstrates the WithMiddleware mount option.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	// Middleware functions would be added here
	// For this example, we show the configuration
	cfg := route.BuildMountConfig(
		route.InheritMiddleware(),
	)

	fmt.Println("InheritMiddleware:", cfg.InheritMiddleware)
}
Output:
InheritMiddleware: true

func WithNotFound

func WithNotFound(h Handler) MountOption

WithNotFound sets a custom 404 handler for the subrouter. This handler is only used when no route matches within the subrouter's prefix.

type MountRouteData

type MountRouteData struct {
	Method           string
	FullPath         string
	Handlers         []Handler
	Constraints      []Constraint
	TypedConstraints map[string]ParamConstraint
	Name             string
	Description      string
	Tags             []string
}

MountRouteData contains route data prepared for mounting with a prefix. It holds all the information needed to register a route from a subrouter.

func PrepareMountRoute

func PrepareMountRoute(prefix string, route *Route, middlewareChain []Handler, namePrefix string) *MountRouteData

PrepareMountRoute creates mount data from a route and prefix.

type ParamConstraint

type ParamConstraint struct {
	Kind    ConstraintKind
	Pattern string   // for ConstraintRegex
	Enum    []string // for ConstraintEnum
	// contains filtered or unexported fields
}

ParamConstraint represents a typed constraint for a route parameter. This provides semantic constraint types that map directly to OpenAPI schema types.

Example (Date)

ExampleParamConstraint_date demonstrates a date constraint.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pc := route.ParamConstraint{Kind: route.ConstraintDate}
	constraint := pc.ToRegexConstraint("date")

	fmt.Println("Matches '2025-12-01':", constraint.Pattern.MatchString("2025-12-01"))
	fmt.Println("Matches '12-01-2025':", constraint.Pattern.MatchString("12-01-2025"))
}
Output:
Matches '2025-12-01': true
Matches '12-01-2025': false
Example (Enum)

ExampleParamConstraint_enum demonstrates an enum constraint.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pc := route.ParamConstraint{
		Kind: route.ConstraintEnum,
		Enum: []string{"draft", "published", "archived"},
	}
	constraint := pc.ToRegexConstraint("status")

	fmt.Println("Matches 'draft':", constraint.Pattern.MatchString("draft"))
	fmt.Println("Matches 'published':", constraint.Pattern.MatchString("published"))
	fmt.Println("Matches 'deleted':", constraint.Pattern.MatchString("deleted"))
}
Output:
Matches 'draft': true
Matches 'published': true
Matches 'deleted': false
Example (Int)

ExampleParamConstraint_int demonstrates an integer constraint.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pc := route.ParamConstraint{Kind: route.ConstraintInt}
	constraint := pc.ToRegexConstraint("id")

	fmt.Println("Matches '123':", constraint.Pattern.MatchString("123"))
	fmt.Println("Matches 'abc':", constraint.Pattern.MatchString("abc"))
}
Output:
Matches '123': true
Matches 'abc': false
Example (Regex)

ExampleParamConstraint_regex demonstrates a custom regex constraint.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pc := route.ParamConstraint{
		Kind:    route.ConstraintRegex,
		Pattern: `[a-z][a-z0-9-]*`,
	}
	pc.Compile() // Compile the regex pattern

	constraint := pc.ToRegexConstraint("slug")

	fmt.Println("Matches 'hello-world':", constraint.Pattern.MatchString("hello-world"))
	fmt.Println("Matches '123abc':", constraint.Pattern.MatchString("123abc"))
}
Output:
Matches 'hello-world': true
Matches '123abc': false
Example (Uuid)

ExampleParamConstraint_uuid demonstrates a UUID constraint.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pc := route.ParamConstraint{Kind: route.ConstraintUUID}
	constraint := pc.ToRegexConstraint("uuid")

	fmt.Println("Matches valid UUID:", constraint.Pattern.MatchString("550e8400-e29b-41d4-a716-446655440000"))
	fmt.Println("Matches invalid:", constraint.Pattern.MatchString("not-a-uuid"))
}
Output:
Matches valid UUID: true
Matches invalid: false

func (*ParamConstraint) Compile

func (pc *ParamConstraint) Compile()

Compile compiles regex patterns in typed constraints (lazy compilation).

func (*ParamConstraint) ToRegexConstraint

func (pc *ParamConstraint) ToRegexConstraint(paramName string) *Constraint

ToRegexConstraint converts a typed constraint to a regex-based Constraint for use with the existing validation system. This allows typed constraints to work with the current router architecture while preserving semantic information for OpenAPI.

type Registrar

type Registrar interface {
	// IsFrozen returns true if routes cannot be modified.
	IsFrozen() bool

	// IsWarmedUp returns true if Warmup() has been called.
	IsWarmedUp() bool

	// AddPendingRoute adds a route to the pending routes list for deferred registration.
	AddPendingRoute(route *Route)

	// RegisterRouteNow registers a route immediately (used after warmup).
	RegisterRouteNow(route *Route)

	// GetGlobalMiddleware returns a copy of the router's global middleware.
	GetGlobalMiddleware() []Handler

	// RecordRouteRegistration records a route registration for metrics/diagnostics.
	RecordRouteRegistration(method, path string)

	// Emit emits a diagnostic event.
	Emit(kind DiagnosticKind, msg string, data map[string]any)

	// UpdateRouteInfo updates route info for introspection when constraints are added.
	UpdateRouteInfo(method, path, version string, update func(info *Info))

	// RegisterNamedRoute registers a named route for reverse routing.
	RegisterNamedRoute(name string, route *Route) error

	// GetRouteCompiler returns the route compiler (for compiled route matching).
	GetRouteCompiler() *compiler.RouteCompiler

	// UseCompiledRoutes returns whether compiled route matching is enabled.
	UseCompiledRoutes() bool

	// AddRouteToTree adds a route to the routing tree.
	AddRouteToTree(method, path string, handlers []Handler, constraints []Constraint)

	// AddVersionRoute adds a route to a version-specific tree.
	AddVersionRoute(version, method, path string, handlers []Handler, constraints []Constraint)

	// StoreRouteInfo stores route info for introspection.
	StoreRouteInfo(info Info)

	// AddRouteWithConstraints adds a route with support for parameter constraints.
	// This is used by Group to add routes.
	AddRouteWithConstraints(method, path string, handlers []Handler) *Route

	// CacheRouteHandlers caches handlers on a compiled route with proper type conversion.
	// This is called by Route.RegisterRoute() to cache handlers for fast lookup.
	CacheRouteHandlers(compiledRoute *compiler.CompiledRoute, handlers []Handler)
}

Registrar is the interface that Router implements to enable route registration. This interface is used by Route and Group to interact with the router without creating an import cycle.

All methods in this interface are called at startup time during route registration, not in the hot path (ServeHTTP). Therefore, interface dispatch overhead is acceptable.

type ReversePattern

type ReversePattern struct {
	Segments []Segment
}

ReversePattern represents a compiled route pattern for URL building (reverse routing). It stores the positions of parameters to avoid string replacements.

func ParseReversePattern

func ParseReversePattern(path string) *ReversePattern

ParseReversePattern parses a route path into segments for URL building. Example: "/users/:id/posts/:postId" -> [{static:"users"}, {param:"id"}, {static:"posts"}, {param:"postId"}]

Example

ExampleParseReversePattern demonstrates parsing a route path into segments for URL building (reverse routing).

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pattern := route.ParseReversePattern("/users/:id/posts/:postId")

	for _, seg := range pattern.Segments {
		if seg.Static {
			fmt.Printf("Static: %s\n", seg.Value)
		} else {
			fmt.Printf("Param: %s\n", seg.Value)
		}
	}
}
Output:
Static: users
Param: id
Static: posts
Param: postId
Example (Simple)

ExampleParseReversePattern_simple demonstrates parsing a simple static path.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pattern := route.ParseReversePattern("/health")

	fmt.Printf("Segments: %d\n", len(pattern.Segments))
	fmt.Printf("First segment static: %v, value: %s\n", pattern.Segments[0].Static, pattern.Segments[0].Value)
}
Output:
Segments: 1
First segment static: true, value: health

func (*ReversePattern) BuildURL

func (p *ReversePattern) BuildURL(params map[string]string, query url.Values) (string, error)

BuildURL builds a URL from the reverse pattern and parameters.

Example

ExampleReversePattern_BuildURL demonstrates building URLs from a parsed pattern.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pattern := route.ParseReversePattern("/users/:id")

	url, err := pattern.BuildURL(map[string]string{"id": "123"}, nil)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println(url)
}
Output:
/users/123
Example (MissingParam)

ExampleReversePattern_BuildURL_missingParam demonstrates the error when a required parameter is missing.

package main

import (
	"fmt"

	"rivaas.dev/router/route"
)

func main() {
	pattern := route.ParseReversePattern("/users/:id")

	_, err := pattern.BuildURL(map[string]string{}, nil)
	if err != nil {
		fmt.Println(err)
	}
}
Output:
missing required parameter: id
Example (WithQuery)

ExampleReversePattern_BuildURL_withQuery demonstrates building URLs with query parameters.

package main

import (
	"fmt"
	"net/url"

	"rivaas.dev/router/route"
)

func main() {
	pattern := route.ParseReversePattern("/users/:id/posts")

	query := url.Values{}
	query.Set("page", "1")
	query.Set("limit", "10")

	result, err := pattern.BuildURL(map[string]string{"id": "42"}, query)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println(result)
}
Output:
/users/42/posts?limit=10&page=1

type Route

type Route struct {
	// contains filtered or unexported fields
}

Route represents a registered route with optional constraints. This provides a fluent interface for adding constraints and metadata.

Routes use deferred registration - they are collected when created but only added to the routing tree during Warmup() or on first request. This allows constraints to be added via fluent API without re-registration issues.

func NewRoute

func NewRoute(registrar Registrar, version, method, path string, handlers []Handler) *Route

NewRoute creates a new Route with the given registrar, method, path, and handlers.

func (*Route) Constraints

func (r *Route) Constraints() []Constraint

Constraints returns the regex-based constraints for this route.

func (*Route) Description

func (r *Route) Description() string

Description returns the route description (empty if not set).

func (*Route) GetVersionGroup

func (r *Route) GetVersionGroup() any

GetVersionGroup returns the version group reference.

func (*Route) Handlers

func (r *Route) Handlers() []Handler

Handlers returns the handler chain for this route.

func (*Route) Method

func (r *Route) Method() string

Method returns the HTTP method for this route.

func (*Route) Name

func (r *Route) Name() string

Name returns the route name (empty if not named). This follows Go naming conventions: getters don't use a Get prefix.

func (*Route) Path

func (r *Route) Path() string

Path returns the route path pattern.

func (*Route) RegisterRoute

func (r *Route) RegisterRoute()

RegisterRoute adds the route to the appropriate radix tree with its constraints. This is called during Warmup() for deferred route registration. The route.version field determines which tree to use:

  • Empty string: standard tree
  • Non-empty: version-specific tree

This method is thread-safe and uses a mutex to prevent double registration.

func (*Route) ReversePattern

func (r *Route) ReversePattern() *ReversePattern

ReversePattern returns the compiled reverse pattern for URL building.

func (*Route) SetDescription

func (r *Route) SetDescription(desc string) *Route

SetDescription sets an optional description for the route. Useful for API documentation generation. Returns the route for method chaining.

Example:

r.GET("/users/:id", getUserHandler).
    SetName("users.get").
    SetDescription("Retrieve a user by ID")

func (*Route) SetGroup

func (r *Route) SetGroup(g *Group)

SetGroup sets the group reference for name prefixing.

func (*Route) SetName

func (r *Route) SetName(name string) *Route

SetName assigns a human-readable name to the route for reverse routing and introspection. Names must be globally unique. Panics if the router is frozen or if the name is already taken. Returns the route for method chaining.

Example:

r.GET("/users/:id", getUserHandler).SetName("users.get")
r.POST("/users", createUserHandler).SetName("users.create")

func (*Route) SetReversePattern

func (r *Route) SetReversePattern(p *ReversePattern)

SetReversePattern sets the compiled reverse pattern.

func (*Route) SetTags

func (r *Route) SetTags(tags ...string) *Route

SetTags adds categorization tags to the route. Useful for grouping routes in documentation and filtering. Returns the route for method chaining.

Example:

r.GET("/users/:id", getUserHandler).
    SetName("users.get").
    SetTags("users", "public", "read")

func (*Route) SetVersionGroup

func (r *Route) SetVersionGroup(vg any)

SetVersionGroup sets the version group reference for name prefixing.

func (*Route) Tags

func (r *Route) Tags() []string

Tags returns the route tags.

func (*Route) TypedConstraints

func (r *Route) TypedConstraints() map[string]ParamConstraint

TypedConstraints returns a copy of the typed constraints map.

func (*Route) Version

func (r *Route) Version() string

Version returns the API version for this route (empty if not versioned).

func (*Route) Where

func (r *Route) Where(param, pattern string) *Route

Where adds a constraint to a route parameter using a regular expression. The constraint is pre-compiled for validation during routing. This method provides a fluent interface for building routes with validation.

IMPORTANT: This method panics if the regex pattern is invalid. This is intentional for validation during application startup. Ensure patterns are tested.

Common patterns:

  • Numeric: `\d+` (one or more digits)
  • Alpha: `[a-zA-Z]+` (letters only)
  • UUID: `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`

Example:

r.GET("/users/:id", getUserHandler).Where("id", `\d+`)
r.GET("/files/:filename", getFileHandler).Where("filename", `[a-zA-Z0-9.-]+`)

The panic on invalid regex is by design for early error detection during development.

func (*Route) WhereDate

func (r *Route) WhereDate(name string) *Route

WhereDate adds a typed constraint that ensures the parameter is an RFC3339 full-date. This maps to OpenAPI schema type "string" with format "date".

Example:

r.GET("/orders/:date", handler).WhereDate("date")

func (*Route) WhereDateTime

func (r *Route) WhereDateTime(name string) *Route

WhereDateTime adds a typed constraint that ensures the parameter is an RFC3339 date-time. This maps to OpenAPI schema type "string" with format "date-time".

Example:

r.GET("/events/:timestamp", handler).WhereDateTime("timestamp")

func (*Route) WhereEnum

func (r *Route) WhereEnum(name string, values ...string) *Route

WhereEnum adds a typed constraint that ensures the parameter matches one of the provided values. This maps to OpenAPI schema type "string" with an enum.

Example:

r.GET("/status/:state", handler).WhereEnum("state", "active", "pending", "deleted")

func (*Route) WhereFloat

func (r *Route) WhereFloat(name string) *Route

WhereFloat adds a typed constraint that ensures the parameter is a floating-point number. This maps to OpenAPI schema type "number" with format "double".

Example:

r.GET("/prices/:amount", handler).WhereFloat("amount")

func (*Route) WhereInt

func (r *Route) WhereInt(name string) *Route

WhereInt adds a typed constraint that ensures the parameter is an integer. This maps to OpenAPI schema type "integer" with format "int64".

Example:

r.GET("/users/:id", handler).WhereInt("id")

func (*Route) WhereRegex

func (r *Route) WhereRegex(name, pattern string) *Route

WhereRegex adds a typed constraint with a custom regex pattern. This maps to OpenAPI schema type "string" with a pattern.

Example:

r.GET("/files/:name", handler).WhereRegex("name", `[a-zA-Z0-9._-]+`)

func (*Route) WhereUUID

func (r *Route) WhereUUID(name string) *Route

WhereUUID adds a typed constraint that ensures the parameter is a valid UUID. This maps to OpenAPI schema type "string" with format "uuid".

Example:

r.GET("/entities/:uuid", handler).WhereUUID("uuid")

type Segment

type Segment struct {
	Static bool   // true if static text, false if parameter
	Value  string // static text or parameter name
}

Segment represents a segment in a route path.

Jump to

Keyboard shortcuts

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