arc

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 16, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

README

arc

Go Reference

arc is a minimal, high-performance HTTP router for Go applications that want to stay close to net/http.

Use it when you want route parameters, method routing, middleware groups, subrouters, mounted handlers, and host-based routing without adopting a web framework. Handlers are ordinary http.Handler and http.HandlerFunc values, middleware is normal handler wrapping, and the router itself can be passed directly to http.ListenAndServe or http.Server.

Path and host matching are powered by github.com/ryanfowler/match.

Install

go get github.com/ryanfowler/arc

Start an Application

Create a router during application startup, register your routes, and pass the router to net/http.

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/ryanfowler/arc"
)

func main() {
	r := arc.New()

	r.Get("/", func(w http.ResponseWriter, req *http.Request) {
		fmt.Fprintln(w, "ok")
	})

	r.Get("/users/{id}", func(w http.ResponseWriter, req *http.Request) {
		id := arc.Param(req, "id")
		fmt.Fprintf(w, "user %s\n", id)
	})

	log.Fatal(http.ListenAndServe(":8080", r))
}

arc.New() returns an *arc.Router, which implements http.Handler. Build it once, then serve requests with it. After registration is complete, the router is safe for concurrent requests.

Register Routes

Most applications use the method helpers:

r.Get("/users/{id}", getUser)
r.Post("/users", createUser)
r.Put("/users/{id}", updateUser)
r.Delete("/users/{id}", deleteUser)

The helpers accept http.HandlerFunc. If you already have an http.Handler, use HandleMethod:

r.HandleMethod(http.MethodGet, "/status", statusHandler)

Use Handle or HandleFunc for a route that should accept any method:

r.Handle("/healthz", http.HandlerFunc(health))

When a path exists but the method does not match, arc returns 405 Method Not Allowed and sets the Allow header.

Write Route Patterns

Route patterns use the match route grammar:

  • /users/{id} captures one non-empty path segment.
  • /assets/{*path} captures the non-empty remainder of the path.
  • Literal paths are preferred over parameter paths.
  • Catch-all parameters must appear at the end of the pattern.
r.Get("/users/me", currentUser)
r.Get("/users/{id}", getUser)
r.Get("/assets/{*path}", serveAsset)

In this example, /users/me uses currentUser, while /users/42 uses getUser.

Trailing slashes are significant by default. A request for /users/42/ does not match /users/{id} unless you relax slash matching:

r := arc.New()
r.SetStrictSlash(false)
r.Get("/users/{id}", getUser) // matches /users/42 and /users/42/

Exact matches still win. If both /users/{id} and /users/{id}/ are registered, /users/42/ uses the explicit trailing-slash route.

GET routes handle HEAD requests by default when there is no explicit HEAD or any-method route for that path. Disable that if your application needs exact method matching:

r := arc.New()
r.SetImplicitHead(false)
r.Get("/users/{id}", getUser) // HEAD /users/42 returns 405

Read Request Parameters

Use arc.Param when you need one parameter:

r.Get("/users/{id}", func(w http.ResponseWriter, req *http.Request) {
	id := arc.Param(req, "id")
	fmt.Fprintln(w, id)
})

Use arc.Params when you need the full parameter set:

params := arc.Params(req)
id, ok := params.TryGet("id")

arc.Params(req) returns arc.RequestParams, an alias of match.Params, so the match.Params methods are available directly: Len, At, Get, TryGet, Seq, AppendTo, and All.

By default, parameters are available through arc.Param and arc.Params only. If your handlers or middleware expect standard library path values, enable that compatibility option during startup. Do it before creating subrouters or host routers that should inherit the setting:

r := arc.New()
r.SetRequestPathValues(true)

Then req.PathValue("id") returns the same value as arc.Param(req, "id").

When the same name is captured at multiple levels, the most specific match wins:

host params < subrouter params < route params

Read the Matched Pattern

arc sets req.Pattern before calling a matched route, mounted handler, or method-not-allowed fallback. The value is the full path pattern registered with the router, including subrouter or mount prefixes:

r.Get("/users/{id}", func(w http.ResponseWriter, req *http.Request) {
	log.Print(req.Pattern) // "/users/{id}"
})

Host patterns are not included in req.Pattern; a route registered under r.Host("{tenant}.example.com").SubRouter("/api") still receives a path-only pattern such as /api/users/{id}. Host captures remain available through arc.Param, arc.Params, and req.PathValue when request path values are enabled.

Middleware can read req.Pattern once the router has selected the route, mount, or method-not-allowed fallback it wraps. That includes route middleware, mounted-handler middleware, child-router middleware for matched child routes, and method-not-allowed middleware. Middleware already registered on a parent router before creating a host router or subrouter runs before the child performs its final route match, so it should not depend on seeing the child's final pattern.

Router not-found fallback handlers receive an empty req.Pattern, even when a host or subrouter prefix matched and contributed parameters. This also clears a pattern left on a request before it entered arc.

Add Middleware

Middleware in arc is the same shape used throughout net/http: a function that receives one handler and returns another.

func logging(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
		log.Printf("%s %s", req.Method, req.URL.Path)
		next.ServeHTTP(w, req)
	})
}

Register middleware with Use:

r := arc.New()
r.Use(logging)
r.Get("/healthz", health)

Middleware applies to routes, subrouters, host routers, and mounted handlers registered after the Use call. Fallback handlers use the router's current middleware stack. Middleware runs in the order it is registered.

This makes it easy to build application sections with different middleware:

r.Get("/healthz", health) // no auth middleware

r.Use(requireAuth)
r.Get("/account", account) // uses requireAuth

Group Application Routes

Use SubRouter when a section of your application shares a path prefix, middleware, or configuration.

r := arc.New()

api := r.SubRouter("/api/{version}")
api.Use(requireAuth)

api.Get("/users/{id}", func(w http.ResponseWriter, req *http.Request) {
	version := arc.Param(req, "version")
	id := arc.Param(req, "id")
	fmt.Fprintf(w, "%s user %s\n", version, id)
})

A subrouter matches the remaining path after the mount point. A child mounted at /api receives /users for a request to /api/users. Both /api and /api/ are dispatched to the child router's / route.

The original request URL is not rewritten for subrouters. Middleware and handlers still see the original req.URL.Path.

Subrouters and direct parent routes share one path matcher. The most specific path wins, so a direct parent route can handle an exact path below a subrouter. Other paths under the subrouter prefix are owned by the child, including not-found and method-not-allowed handling. Register routes on the child when they should use the child's middleware and fallback settings:

api := r.SubRouter("/api")
api.Get("/healthz", healthz) // handles /api/healthz

A parent route such as r.Get("/api/healthz", healthz) handles /api/healthz directly. The /api subrouter still handles other paths below /api.

Mount Existing Handlers

Use Mount when another http.Handler should own everything below a path. This is useful for file servers and other routers.

r := arc.New()
r.Mount("/assets", http.FileServerFS(assets))

Mounted handlers receive the remaining path as req.URL.Path. For example, a handler mounted at /assets receives /app.css for /assets/app.css, while both /assets and /assets/ are dispatched as /.

Mount parameters are available with arc.Param, and with req.PathValue when request path values are enabled.

Mounts and direct parent routes also share one path matcher. The most specific path wins, so a parent route below the mounted prefix handles that exact path. Other paths below the mounted prefix are owned by the mounted handler.

Route by Host

Use Host when different domains or subdomains should have different routes.

r := arc.New()

api := r.Host("api.example.com")
api.Get("/users/{id}", getUser)

tenant := r.Host("{tenant}.example.com")
tenant.Get("/", func(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintf(w, "tenant %s\n", arc.Param(req, "tenant"))
})

Host matching is case-insensitive. If Request.Host includes a port, the port is ignored before matching. Brackets around IPv6 literals are also ignored, so [::1] and [::1]:8080 match the host pattern ::1.

If no host pattern matches, arc continues dispatching on the parent router's subrouters and routes.

Customize Fallbacks

By default:

  • unmatched requests use http.NotFoundHandler;
  • paths registered for a different method receive 405 Method Not Allowed;
  • the Allow header lists the effective methods for that path;
  • when implicit HEAD matching is enabled, Allow includes HEAD for paths with a GET route.

Customize the fallback handlers during startup:

r := arc.New()
r.SetNotFound(http.HandlerFunc(notFound))
r.SetMethodNotAllowed(http.HandlerFunc(methodNotAllowed))

Fallback handlers also receive matched parameters when the host, subrouter, or route pattern captured any. They run through middleware for the router that owns the fallback; a subrouter or host router fallback runs through parent middleware that wrapped the child plus the child router's own middleware.

Handle Registration Errors

The common registration methods panic when a pattern is invalid, duplicated, or ambiguous. That is convenient for applications that register fixed routes at startup:

r.Get("/users/{id}", getUser)

Use the Err variants when routes come from configuration, plugins, or another runtime source:

if err := r.HandleMethodErr(http.MethodGet, "/users/{id}", http.HandlerFunc(getUser)); err != nil {
	return err
}

api, err := r.SubRouterErr("/api/{version}")
if err != nil {
	return err
}

if err := r.MountErr("/assets", http.FileServerFS(assets)); err != nil {
	return err
}

tenant, err := r.HostErr("{tenant}.example.com")
if err != nil {
	return err
}

Route, subrouter, and mount path patterns must begin with /; non-absolute path patterns return arc.ErrInvalidPathPattern. Most other errors come from github.com/ryanfowler/match, including invalid parameter syntax and *match.ConflictError. Patterns that capture the same parameter name more than once return arc.ErrDuplicateParamName.

Configure Before Creating Children

Subrouters and host routers copy the parent router's current settings when they are created. Configure shared behavior first:

r := arc.New()
r.SetStrictSlash(false)
r.SetImplicitHead(false)
r.SetRequestPathValues(true)
r.SetNotFound(http.HandlerFunc(notFound))
r.SetMethodNotAllowed(http.HandlerFunc(methodNotAllowed))

api := r.SubRouter("/api")
api.Get("/users/{id}", getUser)

Later changes on the parent do not affect existing children. Middleware follows the same registration-order model for routes, subrouters, host routers, and mounted handlers. Fallback handlers use the current middleware stack on the router that owns the fallback.

Path Matching Details

arc normally matches req.URL.Path, as parsed by net/http.

When req.URL.RawPath preserves an escaped slash (%2F or %2f), arc matches an internal decoded path where the escaped slash stays inside its path segment. Captured parameters are restored before your handlers read them.

For example, /files/a%2Fb matches /files/{id} and captures a/b, but it does not match the static route /files/a/b.

arc does not clean request paths or issue ServeMux-style redirects for . segments, .. segments, or repeated slashes. Those separators are matched as they appear in the request path, apart from the optional single trailing slash relaxation controlled by SetStrictSlash(false).

Concurrency

Register routes and configure the router before serving requests.

A router is safe for concurrent serving after registration is complete. Registration and configuration methods are not safe to call concurrently with ServeHTTP or with each other.

Documentation

Overview

Package arc helps Go applications route net/http requests without adopting a larger web framework.

The main type is Router. Create one during application startup, register routes and middleware on it, then pass it to http.ListenAndServe or http.Server:

r := arc.New()

r.Get("/users/{id}", func(w http.ResponseWriter, req *http.Request) {
	id := arc.Param(req, "id")
	fmt.Fprintln(w, id)
})

log.Fatal(http.ListenAndServe(":8080", r))

Handlers are ordinary http.Handler and http.HandlerFunc values. Middleware is the standard net/http wrapper shape, so existing middleware can usually be used directly. Arc focuses on dispatch: method routing, route parameters, middleware groups, subrouters, mounted handlers, host routing, and fallback handlers. It does not provide response rendering, request binding, logging, validation, or other framework features.

Route, subrouter, mount, and host patterns use the github.com/ryanfowler/match grammar. Route, subrouter, and mount path patterns must be absolute paths beginning with /. In paths, {name} captures one non-empty segment and {*name} captures the non-empty remainder of the path. Captured parameters are stored on the request and can be read with Params or Param. Use Router.SetRequestPathValues to also expose them through http.Request.PathValue.

Arc also sets http.Request.Pattern for matched routes, mounted handlers, and method-not-allowed fallbacks. The value is the full path pattern, including subrouter or mount prefixes, but it does not include a matched host pattern. Middleware can read Request.Pattern after Arc has selected the route, mount, or method-not-allowed fallback it wraps. Parent middleware that wraps a host router or subrouter runs before the child router's final path match and should not depend on the child's final pattern. Not-found fallback handlers receive an empty Request.Pattern, even when host or subrouter parameters were captured.

Use SubRouter to group a section of an application behind a shared path prefix, Mount to attach an existing http.Handler below a path, and Host to dispatch different domains or subdomains to different routers.

Dispatch checks host routers first. Inside a host or ordinary router, routes, subrouters, and mounted handlers share one path matcher, so the most specific path wins. A direct route below a subrouter or mounted prefix can handle that path; other paths below the prefix remain owned by the child.

Arc normally matches paths using req.URL.Path as parsed by net/http. When req.URL.RawPath preserves an escaped slash, Arc matches an internal decoded path where the escaped slash stays inside its segment, then restores captured parameters before exposing them. It does not perform net/http.ServeMux path cleaning redirects for dot segments or repeated slashes. GET routes handle HEAD requests by default when no explicit HEAD or any-method route matches; use Router.SetImplicitHead to disable that behavior.

Index

Constants

This section is empty.

Variables

View Source
var ErrDuplicateParamName = fmt.Errorf("%w: duplicate parameter names are not allowed within one pattern", match.ErrInvalidParam)

ErrDuplicateParamName reports a single registered pattern that captures the same parameter name more than once.

View Source
var ErrInvalidPathPattern = errors.New("path patterns must begin with /")

ErrInvalidPathPattern reports a route, subrouter, or mount path pattern that is not an absolute HTTP path.

Functions

func Param

func Param(req *http.Request, name string) string

Param returns one named parameter captured while matching req.

Param returns an empty string when name was not captured. Use Params(req). TryGet when callers need to distinguish a missing parameter from a captured empty string, although arc's underlying matcher captures only non-empty values.

Types

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware wraps an HTTP handler on a Router.

Middleware uses the same shape as standard net/http middleware. If a router uses middleware a, b, and c, requests flow through a, then b, then c, then the matched handler or fallback handler.

type RequestParams

type RequestParams = match.Params

RequestParams is the parameter set captured while matching a request.

RequestParams aliases match.Params, so application code can use match's Len, At, Get, TryGet, Seq, AppendTo, and All methods directly.

func Params

func Params(req *http.Request) RequestParams

Params returns the parameters captured while matching req.

The returned value is empty when the request did not match a parameterized host, subrouter, mounted handler, or route. If the same parameter name is captured at multiple levels, the more specific match wins: route parameters override subrouter parameters, and subrouter parameters override host parameters.

type Router

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

Router is an http.Handler that dispatches application requests by host, path, and method.

Build a router during startup by configuring fallback handlers and registering middleware, host routers, subrouters, mounted handlers, and routes. After it is built, pass it to http.Server or http.ListenAndServe.

A Router is safe for concurrent serving after registration is complete. The registration and configuration methods are not safe to call concurrently with ServeHTTP or with other registration and configuration methods.

func New

func New() *Router

New creates a Router with defaults suitable for a typical net/http application.

By default, unmatched requests use http.NotFoundHandler and requests whose path matches a route registered for a different method receive 405 Method Not Allowed. GET routes also handle HEAD requests unless an explicit HEAD or any-method route matches.

Child routers and host routers copy the parent router's current settings when they are created.

func (*Router) Delete

func (r *Router) Delete(pattern string, h http.HandlerFunc)

Delete registers h for DELETE requests matching pattern.

func (*Router) Get

func (r *Router) Get(pattern string, h http.HandlerFunc)

Get registers h for GET requests matching pattern.

By default, the route also handles HEAD requests when no explicit HEAD or any-method route matches. Use Router.SetImplicitHead(false) to require an explicit HEAD route.

func (*Router) Handle

func (r *Router) Handle(pattern string, h http.Handler)

Handle registers h for pattern and lets it handle any request method.

Use Handle for endpoints such as health checks or webhooks where the handler should decide which methods are acceptable. The pattern uses the github.com/ryanfowler/match route grammar; for example, /users/{id} captures one segment and /assets/{*path} captures the remaining path.

Routes, subrouters, and mounted handlers share one path matcher on the same router. The most specific path wins, so a direct route below a mounted prefix, such as /api/healthz when /api is a subrouter or mount, handles that path.

Invalid, duplicate, or ambiguous patterns panic with the error returned by match. Use HandleErr to receive the registration error instead.

func (*Router) HandleErr

func (r *Router) HandleErr(pattern string, h http.Handler) error

HandleErr registers h for pattern, lets it handle any request method, and returns registration errors.

The pattern uses the github.com/ryanfowler/match route grammar. Registration errors include non-absolute path patterns, invalid parameter syntax, duplicate parameter names within the pattern, and route conflicts reported by match. A nil handler is treated as http.NotFoundHandler.

Routes, subrouters, and mounted handlers share one path matcher on the same router. The most specific path wins, so a direct route below a mounted prefix handles that path.

func (*Router) HandleFunc

func (r *Router) HandleFunc(pattern string, h http.HandlerFunc)

HandleFunc registers h for pattern and lets it handle any request method.

HandleFunc is a convenience wrapper around Handle.

func (*Router) HandleMethod

func (r *Router) HandleMethod(method, pattern string, h http.Handler)

HandleMethod registers h for one HTTP method and pattern.

Use HandleMethod when you have an http.Handler value. For http.HandlerFunc handlers, the method helpers such as Get and Post are usually shorter.

The pattern uses the github.com/ryanfowler/match route grammar. Invalid, duplicate, or ambiguous patterns panic with the error returned by match. Use HandleMethodErr to receive the registration error instead.

func (*Router) HandleMethodErr

func (r *Router) HandleMethodErr(method, pattern string, h http.Handler) error

HandleMethodErr registers h for one HTTP method and pattern and returns registration errors.

The pattern uses the github.com/ryanfowler/match route grammar. Registration errors include non-absolute path patterns, invalid parameter syntax, duplicate parameter names within the pattern, and route conflicts reported by match. A nil handler is treated as http.NotFoundHandler.

func (*Router) HandleMethodFunc

func (r *Router) HandleMethodFunc(method, pattern string, h http.HandlerFunc)

HandleMethodFunc registers h for one HTTP method and pattern.

HandleMethodFunc is a convenience wrapper around HandleMethod.

func (*Router) Head

func (r *Router) Head(pattern string, h http.HandlerFunc)

Head registers h for HEAD requests matching pattern.

func (*Router) Host

func (r *Router) Host(pattern string) *Router

Host registers and returns a child router for requests whose host matches pattern.

Use Host when one application serves different routes for different domains or subdomains. Host patterns use the github.com/ryanfowler/match grammar, for example "api.example.com" or "{tenant}.example.com". Request hosts are matched case-insensitively, a port in Request.Host is ignored, and brackets around IPv6 literals are ignored.

Parameters captured by the host pattern are available to handlers registered on the returned router. If no host pattern matches, dispatch falls through to the parent router's subrouters and routes.

Middleware already registered on the parent wraps the host router. Middleware added to the returned router applies only inside that host router, including host-router fallback handlers. The returned router copies the parent's current strict slash, implicit HEAD, request path value, and fallback handler settings when it is created.

Invalid, duplicate, or ambiguous host patterns panic with the error returned by match. Use HostErr to receive the registration error instead.

func (*Router) HostErr

func (r *Router) HostErr(pattern string) (*Router, error)

HostErr registers and returns a child router for requests whose host matches pattern, and returns registration errors.

Host patterns use the github.com/ryanfowler/match grammar. Registration errors include invalid parameter syntax, duplicate parameter names within the pattern, and host conflicts reported by match.

func (*Router) Mount

func (r *Router) Mount(pattern string, h http.Handler)

Mount registers h below pattern and lets that handler own the remaining path.

Use Mount for file servers, another router, or any existing http.Handler that should handle everything below a path. The pattern uses the github.com/ryanfowler/match route grammar. Parameters captured by the mount pattern are available to middleware and the mounted handler.

The mounted handler receives the remaining path after the mount point as req.URL.Path. For example, a handler mounted at /assets receives /app.css for a request to /assets/app.css, while both /assets and /assets/ are dispatched as /. Middleware already registered on the parent sees the original request path and wraps the mounted handler.

Mounted handlers and direct parent routes share one path matcher. The most specific path wins, so a parent route below the mounted prefix, such as /assets/healthz, handles that exact path. Other paths under the mounted prefix are owned by the mounted handler.

Invalid, duplicate, or ambiguous mount patterns panic with the error returned by match. Use MountErr to receive the registration error instead.

func (*Router) MountErr

func (r *Router) MountErr(pattern string, h http.Handler) error

MountErr registers h below pattern and returns registration errors.

The pattern uses the github.com/ryanfowler/match route grammar. An empty pattern is treated as /. Registration errors include non-absolute path patterns, invalid parameter syntax, duplicate parameter names within the pattern, and mount conflicts reported by match. A nil handler is treated as http.NotFoundHandler.

func (*Router) Options

func (r *Router) Options(pattern string, h http.HandlerFunc)

Options registers h for OPTIONS requests matching pattern.

func (*Router) Patch

func (r *Router) Patch(pattern string, h http.HandlerFunc)

Patch registers h for PATCH requests matching pattern.

func (*Router) Post

func (r *Router) Post(pattern string, h http.HandlerFunc)

Post registers h for POST requests matching pattern.

func (*Router) Put

func (r *Router) Put(pattern string, h http.HandlerFunc)

Put registers h for PUT requests matching pattern.

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP dispatches req to the best matching host router, route, subrouter, or mounted handler.

Dispatch checks host routers first. Inside a host or ordinary router, routes, subrouters, and mounted handlers share one path matcher, so the most specific path wins. A route registered directly on a router can therefore handle a path below a subrouter or mounted prefix; other paths below that prefix are still owned by the child, including not-found and method-not-allowed handling.

Route and subrouter matching uses req.URL.Path unless req.URL.RawPath preserves an escaped slash. In that case, Arc matches an internal decoded path where the escaped slash stays inside its segment and restores captured params before exposing them. Arc does not perform net/http.ServeMux path cleaning redirects.

ServeHTTP satisfies http.Handler. It should usually be called by net/http rather than directly.

func (*Router) SetImplicitHead

func (r *Router) SetImplicitHead(enabled bool)

SetImplicitHead controls whether HEAD requests may use GET routes when no explicit HEAD or any-method route matches.

Implicit HEAD matching is enabled by default. Explicit HEAD and any-method routes take precedence when present.

func (*Router) SetMethodNotAllowed

func (r *Router) SetMethodNotAllowed(h http.Handler)

SetMethodNotAllowed sets the handler used when a request path matches a route pattern, but the request method was not registered for that pattern.

The handler runs through the router's current middleware stack.

Passing nil leaves the router's existing method-not-allowed handler unchanged.

func (*Router) SetNotFound

func (r *Router) SetNotFound(h http.Handler)

SetNotFound sets the application handler used when no host, subrouter, mounted handler, or route matches a request.

The handler runs through the router's current middleware stack.

Passing nil leaves the router's existing not-found handler unchanged.

func (*Router) SetRequestPathValues

func (r *Router) SetRequestPathValues(enabled bool)

SetRequestPathValues controls whether captured parameters are mirrored to http.Request.PathValue.

Request path values are disabled by default. Enable this when middleware or handlers need to read route parameters with req.PathValue instead of arc.Param or arc.Params.

Subrouters and host routers copy this setting when they are created. Later changes on the parent do not affect existing children.

func (*Router) SetStrictSlash

func (r *Router) SetStrictSlash(strict bool)

SetStrictSlash controls whether route matching treats a trailing slash as significant.

Strict slash matching is enabled by default. When disabled, a request path ending in "/" may match a route registered without that final slash. Exact route matches still take precedence.

Subrouters and host routers copy this setting when they are created. Later changes on the parent do not affect existing children.

func (*Router) SubRouter

func (r *Router) SubRouter(pattern string) *Router

SubRouter registers and returns a child router for an application section mounted at pattern.

Use a subrouter when several routes share a path prefix, middleware, fallback handlers, or slash/method settings. The pattern uses the github.com/ryanfowler/match route grammar. Parameters captured by the mount pattern are available to child middleware and handlers.

The child matches against the remaining path after the mount point. For example, a child mounted at /api matches /users for a request to /api/users, while both /api and /api/ are dispatched to the child's / route. The request URL is not rewritten; middleware and handlers still see the original req.URL.Path.

Subrouters and direct parent routes share one path matcher. The most specific path wins, so a parent route such as /api/healthz handles that exact path even when /api is a subrouter. Other paths under the subrouter prefix are owned by the child, including child not-found and method-not-allowed handling. Register routes such as /api/healthz on the child as /healthz when they should use the child's middleware and fallback settings.

Middleware already registered on the parent wraps the child router. Middleware added to the child applies only inside the child router, including child fallback handlers. The child copies the parent's current strict slash, implicit HEAD, request path value, and fallback handler settings when it is created.

Invalid, duplicate, or ambiguous mount patterns panic with the error returned by match. Use SubRouterErr to receive the registration error instead.

func (*Router) SubRouterErr

func (r *Router) SubRouterErr(pattern string) (*Router, error)

SubRouterErr registers and returns a child router mounted at pattern and returns registration errors.

The pattern uses the github.com/ryanfowler/match route grammar. An empty pattern is treated as /. Registration errors include non-absolute path patterns, invalid parameter syntax, duplicate parameter names within the pattern, and mount conflicts reported by match.

func (*Router) Use

func (r *Router) Use(mw ...Middleware)

Use appends middleware to the router.

Middleware applies only to routes, subrouters, host routers, and mounted handlers registered after the call to Use. Fallback handlers use the router's current middleware stack. This lets applications build separate sections of a router with different middleware stacks. Middleware is executed in the order it is added. Use panics if any middleware is nil.

Jump to

Keyboard shortcuts

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