Documentation
¶
Overview ¶
Package goji is a minimalistic and flexible context based route matching request multiplexer.
Index ¶
- func Param(req *http.Request, name string) string
- func Path(ctx context.Context) string
- func SubMux(m *Mux)
- func WithHandler(ctx context.Context, handler http.Handler) context.Context
- func WithMatcher(ctx context.Context, matcher Matcher) context.Context
- func WithPath(ctx context.Context, path string) context.Context
- type Matcher
- type Mux
- type MuxOption
- type PathSpec
- type PathSpecOption
- type Router
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Param ¶
Param returns a bound, named variable from the context.
For example, given a mux with a single GET route:
mux := goji.NewMux()
mux.HandleFunc(goji.Get("/user/:name"), http.HandlerFunc(/* ... */)
When a HTTP request for is issued:
GET /user/carl
Then a call to goji.Param(req.Context(), "name") will return "carl".
Note: caller should ensure that the variable has been bound. Attempts to access variables that have not been set (or which have been invalidly set) are considered programmer errors and will trigger a panic.
func WithHandler ¶
WithHandler returns a child context with the passed handler.
func WithMatcher ¶
WithMatcher returns a child context with the passed Matcher.
Types ¶
type Matcher ¶
type Matcher interface {
// Match examines the input Request to determine if it matches some
// criteria, and if so returns a non-nil output Request.
Match(*http.Request) *http.Request
// Methods returns the set of HTTP methods that the Matcher matches, or nil
// if it's not possible to determine which HTTP methods might be matched.
Methods() map[string]struct{}
// Prefix returns a string which all RawPaths that the Matcher must
// have as a prefix. Put another way, requests with RawPaths that do not
// contain the returned string as a prefix are guaranteed to never match
// this Matcher.
Prefix() string
}
Matcher determines whether a given request matches some criteria.
type Mux ¶
type Mux struct {
// contains filtered or unexported fields
}
Mux is a HTTP multiplexer and router similar to net/http.ServeMux.
Muxes multiplex traffic between many http.Handlers by selecting the first route registered to a supplied Matcher.
They then call a common middleware stack, finally passing control to the selected http.Handler. See the documentation on the Handle function for more information about how routing is performed, the documentation on the Pattern type for more information about request matching, and the documentation for the Use method for more about middleware.
Muxes cannot be configured concurrently from multiple goroutines, nor can they be configured concurrently with requests.
func NewSubMux ¶
NewSubMux returns a new sub-Mux with no configured middleware using the default router.
func (*Mux) Handle ¶
Handle adds a new route to the Mux. Requests that match the given Matcher will be dispatched to the given http.Handler.
Routing is performed in the order in which routes are added: the first route with a matching Matcher will be used. In particular, Goji guarantees that routing is performed in a manner that is indistinguishable from the following algorithm:
// Assume routes is a slice that every call to Handle appends to
for _, route := range routes {
// For performance, Matchers can opt out of this call to Match.
// See the documentation for Matcher for more.
if req2 := route.pattern.Match(req); req2 != nil {
route.handler.ServeHTTP(res, req2)
break
}
}
It is not safe to concurrently register routes from multiple goroutines, or to register routes concurrently with requests.
func (*Mux) HandleFunc ¶
HandleFunc adds a new route to the Mux. It is equivalent to calling Handle on a handler wrapped with http.HandlerFunc, and is provided only for convenience.
func (*Mux) ServeHTTP ¶
func (m *Mux) ServeHTTP(res http.ResponseWriter, req *http.Request)
ServeHTTP satisfies the http.Handler interface.
func (*Mux) Use ¶
Use appends a middleware to the Mux's middleware stack.
Middleware are composable pieces of functionality that augment http.Handlers. Common examples of middleware include request loggers, authentication checkers, and metrics gatherers.
Middleware are evaluated in the reverse order in which they were added, but the resulting http.Handlers execute in "normal" order (i.e., the http.Handler returned by the first Middleware to be added gets called first).
For instance, given middleware A, B, and C, added in that order, Goji will behave similarly to this snippet:
augmentedHandler := A(B(C(yourHandler))) augmentedHandler.ServeHTTP(res, req)
Assuming each of A, B, and C look something like this:
func A(inner http.Handler) http.Handler {
log.Print("A: called")
mw := func(res http.ResponseWriter, req *http.Request) {
log.Print("A: before")
inner.ServeHTTP(res, req)
log.Print("A: after")
}
return http.HandlerFunc(mw)
}
we'd expect to see the following in the log:
C: called B: called A: called --- A: before B: before C: before yourHandler: called C: after B: after A: after
Note that augmentedHandler will called many times, producing the log output below the divider, while the outer middleware functions (the log output above the divider) will only be called a handful of times at application boot.
Middleware in Goji is called after routing has been performed. Therefore it is possible to examine any routing information placed into the Request context by Patterns, or to view or modify the http.Handler that will be routed to. Middleware authors should read the documentation for the "middleware" subpackage for more information about how this is done.
The http.Handler returned by the given middleware must be safe for concurrent use by multiple goroutines. It is not safe to concurrently register middleware from multiple goroutines, or to register middleware concurrently with requests.
type MuxOption ¶
type MuxOption func(*Mux)
MuxOption is a Mux option.
func NotFoundFunc ¶
func NotFoundFunc(f http.HandlerFunc) MuxOption
NotFoundFunc is a mux option to set a not found (404) handler func.
type PathSpec ¶
type PathSpec struct {
// contains filtered or unexported fields
}
PathSpec provides a Matcher that matches requests routes based on named path components, storing matched path components in the request context.
Quick Reference ¶
The following table gives an overview of the language this package accepts. See the subsequent sections for a more detailed explanation of what each path does.
Path Matches Does Not Match / / /hello /hello /hello /hi /hello/ /user/:name /user/carl /user/carl/photos /user/alice /user/carl/ /user/ /:file.:ext /data.json /.json /info.txt /data. /data.tar.gz /data.json/download /user/* /user/ /user /user/carl /user/carl/photos
Static Paths ¶
Most URL paths may be specified directly: the pattern "/hello" matches URLs with precisely that path ("/hello/", for instance, is treated as distinct).
Note that this package operates on raw (i.e., escaped) paths (see the documentation for net/url.URL.EscapedPath). In order to match a character that can appear escaped in a URL path, use its percent-encoded form.
Named Matches ¶
Named matches allow URL paths to contain any value in a particular path segment. Such matches are denoted by a leading ":", for example ":name" in the rule "/user/:name", and permit any non-empty value in that position. For instance, in the previous "/user/:name" example, the path "/user/carl" is matched, while "/user/" or "/user/carl/" (note the trailing slash) are not matched. Pat rules can contain any number of named matches.
Named matches set URL variables by comparing pattern names to the segments they matched. In our "/user/:name" example, a request for "/user/carl" would bind the "name" variable to the value "carl". Use the Param function to extract these variables from the request context. Variable names in a single pattern must be unique.
Matches are ordinarily delimited by slashes ("/"), but several other characters are accepted as delimiters (with slightly different semantics): the period ("."), semicolon (";"), and comma (",") characters. For instance, given the pattern "/:file.:ext", the request "/data.json" would match, binding "file" to "data" and "ext" to "json". Note that these special characters are treated slightly differently than slashes: the above pattern also matches the path "/data.tar.gz", with "ext" getting set to "tar.gz"; and the pattern "/:file" matches names with dots in them (like "data.json").
Prefix Matches ¶
Pat can also match prefixes of routes using wildcards. Prefix wildcard routes end with "/*", and match just the path segments preceding the asterisk. For instance, the pattern "/user/*" will match "/user/" and "/user/carl/photos" but not "/user" (note the lack of a trailing slash).
The unmatched suffix, including the leading slash ("/"), are placed into the request context, which allows subsequent routing (e.g., a subrouter) to continue from where this pattern left off. For instance, in the "/user/*" pattern from above, a request for "/user/carl/photos" will consume the "/user" prefix, leaving the path "/carl/photos" for subsequent patterns to handle. A subrouter pattern for "/:name/photos" would match this remaining path segment, for instance.
func Get ¶
Get returns a PathSpec that matches requests for GET and HEAD HTTP method. HEAD requests are handled transparently by net/http.
func NewPathSpec ¶
func NewPathSpec(spec string, opts ...PathSpecOption) *PathSpec
NewPathSpec returns a new PathSpec from the given path spec and options.
func (*PathSpec) Match ¶
Match runs the path spec against the passed request, returning a modified copy of the request when the path spec matches.
type PathSpecOption ¶
type PathSpecOption func(*PathSpec)
PathSpecOption is a path spec option.
func WithMethod ¶
func WithMethod(methods ...string) PathSpecOption
WithMethod is a path spec option to set the matching HTTP methods.