Documentation
¶
Index ¶
- Constants
- Variables
- func Bind[T any](_ T) http.HandlerFunc
- func GetForm(dataStore reqctx.RequestDataStore) any
- func RegisterResponseStatusProvider[T any](fn func(req *http.Request) types.ResponseStatusProvider)
- func RouteMock(pointName string, h any) func()
- func RouteMockReset()
- func RouterMockPoint(pointName string) func(next http.Handler) http.Handler
- func SetForm(dataStore reqctx.ContextDataProvider, obj any)
- func WithRouteContext(req *http.Request, rc *RouteContext) *http.Request
- type Combo
- type Mux
- func (m *Mux) Method(method, pattern string, h http.Handler)
- func (m *Mux) Mount(pattern string, h http.Handler)
- func (m *Mux) NotFound(h http.Handler)
- func (m *Mux) NotFoundHandler() http.Handler
- func (m *Mux) ServeHTTP(resp http.ResponseWriter, req *http.Request)
- func (m *Mux) Use(mw func(http.Handler) http.Handler)
- type RouteContext
- type Router
- func (r *Router) AfterRouting(middlewares ...any)
- func (r *Router) Any(pattern string, h ...any)
- func (r *Router) BeforeRouting(middlewares ...any)
- func (r *Router) Combo(pattern string, h ...any) *Combo
- func (r *Router) Delete(pattern string, h ...any)
- func (r *Router) Get(pattern string, h ...any)
- func (r *Router) Group(pattern string, fn func(), middlewares ...any)
- func (r *Router) Head(pattern string, h ...any)
- func (r *Router) Methods(methods, pattern string, h ...any)
- func (r *Router) Mount(pattern string, subRouter *Router)
- func (r *Router) NotFound(h http.HandlerFunc)
- func (r *Router) Patch(pattern string, h ...any)
- func (r *Router) PathGroup(pattern string, fn func(g *RouterPathGroup), h ...any)
- func (r *Router) Post(pattern string, h ...any)
- func (r *Router) Put(pattern string, h ...any)
- func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
- type RouterPathGroup
- func (g *RouterPathGroup) MatchPath(methods, pattern string, h ...any)
- func (g *RouterPathGroup) MatchPattern(methods string, pattern *RouterPathGroupPattern, h ...any)
- func (g *RouterPathGroup) PatternRegexp(pattern string, h ...any) *RouterPathGroupPattern
- func (g *RouterPathGroup) ServeHTTP(resp http.ResponseWriter, req *http.Request)
- type RouterPathGroupPattern
Constants ¶
const MockAfterMiddlewares = "MockAfterMiddlewares"
MockAfterMiddlewares is a general mock point, it's between middlewares and the handler
Variables ¶
var RouteCtxKey = routeCtxKey{}
RouteCtxKey is the context key a RouteContext is stored under. Exported so test helpers can build a routed-looking request without a router.
Functions ¶
func GetForm ¶
func GetForm(dataStore reqctx.RequestDataStore) any
GetForm returns the validate form information
func RegisterResponseStatusProvider ¶
func RegisterResponseStatusProvider[T any](fn func(req *http.Request) types.ResponseStatusProvider)
func RouteMock ¶
RouteMock uses the registered mock point to mock the route execution, example:
defer web.RouteMockReset()
web.RouteMock(web.MockAfterMiddlewares, func(ctx *context.Context) {
ctx.WriteResponse(...)
}
Then the mock function will be executed as a middleware at the mock point. It only takes effect in testing mode (setting.IsInTesting == true).
func RouterMockPoint ¶
RouterMockPoint registers a mock point as a middleware for testing, example:
r.Use(web.RouterMockPoint("my-mock-point-1"))
r.Get("/foo", middleware2, web.RouterMockPoint("my-mock-point-2"), middleware2, handler)
Then use web.RouteMock to mock the route execution. It only takes effect in testing mode (setting.IsInTesting == true).
func SetForm ¶
func SetForm(dataStore reqctx.ContextDataProvider, obj any)
SetForm set the form object
func WithRouteContext ¶ added in v1.26.27
func WithRouteContext(req *http.Request, rc *RouteContext) *http.Request
WithRouteContext attaches rc to req so handlers below can read the captured parameters.
Types ¶
type Combo ¶
type Combo struct {
// contains filtered or unexported fields
}
Combo represents a tiny group routes with same pattern
type Mux ¶ added in v1.26.27
type Mux struct {
// contains filtered or unexported fields
}
Mux routes requests to handlers. It replaces the chi router.
The tree is over path SEGMENTS, and a node tries its children in order of how specific they are: an exact segment, then patterned segments in the order they were registered, then a trailing wildcard. That ordering is the whole contract — "/user/settings" must win over "/user/{name}" no matter which was registered first, or a user called "settings" takes over the settings page.
Matching backtracks. A segment can match here and fail deeper, and the next candidate at this level still has to be tried: "/{username}/{reponame}" and "/{username}/settings" share a first segment, so failing the second segment under one is not failure of the route.
Four segment shapes appear in this codebase's 1333 routes, and all four are supported deliberately rather than by accident:
users static
{id} whole-segment parameter
{sha:[a-f0-9]+} parameter with a regexp constraint (43 of them)
PACKAGES{format} parameter that is only PART of a segment (CRAN indexes)
* trailing wildcard, captured as the "*" parameter
func (*Mux) Method ¶ added in v1.26.27
Method registers h for one method. An empty method matches any.
func (*Mux) Mount ¶ added in v1.26.27
Mount attaches h to everything under pattern. The subtree handler sees the full path: this forge's mounted routers match on it themselves.
func (*Mux) NotFound ¶ added in v1.26.27
NotFound sets the handler for requests that match no route.
func (*Mux) NotFoundHandler ¶ added in v1.26.27
NotFoundHandler returns the configured miss handler, or the standard one.
type RouteContext ¶ added in v1.26.27
type RouteContext struct {
// RouteMethod is the method the route was matched with. It can differ from
// req.Method: a HEAD is routed as a GET.
RouteMethod string
// RoutePatterns records every pattern matched to reach the handler, in
// order, so nested groups can be reconstructed for logging and metrics.
RoutePatterns []string
// RoutePath overrides the path the mux routes on. The normalising middleware
// sets it so an escaped path routes as its decoded form.
RoutePath string
// contains filtered or unexported fields
}
RouteContext carries what a matched route knows: the method it matched, the parameters it captured, and the patterns it matched along the way.
This is data, not routing. The regex matching that fills it lives in routerPathMatcher, which this package has always owned — chi was only holding these three fields on the way through, so depending on a router for them made the router look load-bearing when it was not.
func GetRouteContext ¶ added in v1.26.27
func GetRouteContext(ctx context.Context) *RouteContext
GetRouteContext returns the RouteContext on ctx, or nil when the request was not routed through this package.
func NewRouteContext ¶ added in v1.26.27
func NewRouteContext() *RouteContext
NewRouteContext returns an empty RouteContext ready to accumulate parameters.
func (*RouteContext) Param ¶ added in v1.26.27
func (rc *RouteContext) Param(name string) string
Param returns a captured parameter, or "" when the route did not capture it.
func (*RouteContext) ParamNames ¶ added in v1.26.27
func (rc *RouteContext) ParamNames() []string
ParamNames returns the captured names in the order they were first set.
func (*RouteContext) RoutePattern ¶ added in v1.26.27
func (rc *RouteContext) RoutePattern() string
RoutePattern is the full pattern that matched, with the wildcards that mounting contributes collapsed away.
Each Mount appends its own "/*" to RoutePatterns, so a plain join yields "/v1/*/repos/{username}/*/branches/..." — the stars are an artefact of how the route was assembled, not part of the route. They are removed so the value is the pattern a reader would have written, which is what logs and metrics group by.
func (*RouteContext) SetParam ¶ added in v1.26.27
func (rc *RouteContext) SetParam(name, value string)
SetParam records a captured parameter.
Last write wins, and the first position is kept. A nested group can re-capture a name the outer group already set — the inner value is the more specific one, but reordering the parameters would change what a caller iterating them sees.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router defines a route based on chi's router
func (*Router) AfterRouting ¶
AfterRouting adds middlewares which will be executed after the request path gets routed It can see the routed path and resolved path parameters
func (*Router) BeforeRouting ¶
BeforeRouting adds middlewares which will be executed before the request path gets routed It should only be used for framework-level global middlewares when it needs to change request method & path.
func (*Router) Methods ¶
Methods adds the same handlers for multiple http "methods" (separated by ","). If any method is invalid, the lower level router will panic.
func (*Router) NotFound ¶
func (r *Router) NotFound(h http.HandlerFunc)
NotFound defines a handler to respond whenever a route could not be found.
func (*Router) PathGroup ¶
func (r *Router) PathGroup(pattern string, fn func(g *RouterPathGroup), h ...any)
PathGroup creates a group of paths which could be matched by regexp. It is only designed to resolve some special cases which chi router can't handle. For most cases, it shouldn't be used because it needs to iterate all rules to find the matched one (inefficient).
type RouterPathGroup ¶
type RouterPathGroup struct {
// contains filtered or unexported fields
}
func (*RouterPathGroup) MatchPath ¶
func (g *RouterPathGroup) MatchPath(methods, pattern string, h ...any)
MatchPath matches the request method, and uses regexp to match the path. The pattern uses "<...>" to define path parameters, for example, "/<name>" (different from chi router) It is only designed to resolve some special cases that chi router can't handle. For most cases, it shouldn't be used because it needs to iterate all rules to find the matched one (inefficient).
func (*RouterPathGroup) MatchPattern ¶
func (g *RouterPathGroup) MatchPattern(methods string, pattern *RouterPathGroupPattern, h ...any)
func (*RouterPathGroup) PatternRegexp ¶
func (g *RouterPathGroup) PatternRegexp(pattern string, h ...any) *RouterPathGroupPattern
func (*RouterPathGroup) ServeHTTP ¶
func (g *RouterPathGroup) ServeHTTP(resp http.ResponseWriter, req *http.Request)
type RouterPathGroupPattern ¶
type RouterPathGroupPattern struct {
// contains filtered or unexported fields
}