Documentation ¶
Overview ¶
Package web provides a fast and flexible middleware stack and mux.
This package attempts to solve three problems that net/http does not. First, it allows you to specify flexible patterns, including routes with named parameters and regular expressions. Second, it allows you to write reconfigurable middleware stacks. And finally, it allows you to attach additional context to requests, in a manner that can be manipulated by both compliant middleware and handlers.
A usage example:
m := web.New()
Use your favorite HTTP verbs and the interfaces you know and love from net/http:
var legacyFooHttpHandler http.Handler // From elsewhere m.Get("/foo", legacyFooHttpHandler) m.Post("/bar", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello world!")) })
Bind parameters using either named captures or regular expressions:
m.Get("/hello/:name", func(c web.C, w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", c.URLParams["name"]) }) pattern := regexp.MustCompile(`^/ip/(?P<ip>(?:\d{1,3}\.){3}\d{1,3})$`) m.Get(pattern, func(c web.C, w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Info for IP address %s:", c.URLParams["ip"]) })
Middleware are functions that wrap http.Handlers, just like you'd use with raw net/http. Middleware functions can optionally take a context parameter, which will be threaded throughout the middleware stack and to the final handler, even if not all of the intervening middleware or handlers support contexts. Middleware are encouraged to use the Env parameter to pass request-scoped data to other middleware and to the final handler:
func LoggerMiddleware(h http.Handler) http.Handler { handler := func(w http.ResponseWriter, r *http.Request) { log.Println("Before request") h.ServeHTTP(w, r) log.Println("After request") } return http.HandlerFunc(handler) } func AuthMiddleware(c *web.C, h http.Handler) http.Handler { handler := func(w http.ResponseWriter, r *http.Request) { if cookie, err := r.Cookie("user"); err == nil { c.Env["user"] = cookie.Value } h.ServeHTTP(w, r) } return http.HandlerFunc(handler) } // This makes the AuthMiddleware above a little cleaner m.Use(middleware.EnvInit) m.Use(AuthMiddleware) m.Use(LoggerMiddleware) m.Get("/baz", func(c web.C, w http.ResponseWriter, r *http.Request) { if user, ok := c.Env["user"].(string); ok { w.Write([]byte("Hello " + user)) } else { w.Write([]byte("Hello Stranger!")) } })
Index ¶
- Constants
- type C
- type Handler
- type HandlerFunc
- type Mux
- func (m *Mux) Abandon(middleware interface{}) error
- func (m *Mux) Compile()
- func (m *Mux) Connect(pattern interface{}, handler interface{})
- func (m *Mux) Delete(pattern interface{}, handler interface{})
- func (m *Mux) Get(pattern interface{}, handler interface{})
- func (m *Mux) Handle(pattern interface{}, handler interface{})
- func (m *Mux) Head(pattern interface{}, handler interface{})
- func (m *Mux) Insert(middleware, before interface{}) error
- func (m *Mux) NotFound(handler interface{})
- func (m *Mux) Options(pattern interface{}, handler interface{})
- func (m *Mux) Patch(pattern interface{}, handler interface{})
- func (m *Mux) Post(pattern interface{}, handler interface{})
- func (m *Mux) Put(pattern interface{}, handler interface{})
- func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (m *Mux) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request)
- func (m *Mux) Trace(pattern interface{}, handler interface{})
- func (m *Mux) Use(middleware interface{})
- type Pattern
Constants ¶
const ValidMethodsKey = "goji.web.validMethods"
The key used to communicate to the NotFound handler what methods would have been allowed if they'd been provided.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type C ¶
type C struct { // URLParams is a map of variables extracted from the URL (typically // from the path portion) during routing. See the documentation for the // URL Pattern you are using (or the documentation for ParsePattern for // the case of standard pattern types) for more information about how // variables are extracted and named. URLParams map[string]string // Env is a free-form environment for storing request-local data. Keys // may be arbitrary types that support equality, however package-private // types with type-safe accessors provide a convenient way for packages // to mediate access to their request-local data. Env map[interface{}]interface{} }
C is a request-local context object which is threaded through all compliant middleware layers and given to the final request handler.
type Handler ¶
type Handler interface {
ServeHTTPC(C, http.ResponseWriter, *http.Request)
}
Handler is similar to net/http's http.Handler, but also accepts a Goji context object.
type HandlerFunc ¶
type HandlerFunc func(C, http.ResponseWriter, *http.Request)
HandlerFunc is similar to net/http's http.HandlerFunc, but supports a context object. Implements both http.Handler and web.Handler.
func (HandlerFunc) ServeHTTP ¶
func (h HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements http.Handler, allowing HandlerFunc's to be used with net/http and other compliant routers. When used in this way, the underlying function will be passed an empty context.
func (HandlerFunc) ServeHTTPC ¶
func (h HandlerFunc) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request)
ServeHTTPC implements Handler.
type Mux ¶
type Mux struct {
// contains filtered or unexported fields
}
Mux is an HTTP multiplexer, much like net/http's ServeMux.
Routes may be added using any of the various HTTP-method-specific functions. When processing a request, when iterating in insertion order the first route that matches both the request's path and method is used.
There are two other differences worth mentioning between web.Mux and http.ServeMux. First, string patterns (i.e., Sinatra-like patterns) must match exactly: the "rooted subtree" behavior of ServeMux is not implemented. Secondly, unlike ServeMux, Mux does not support Host-specific patterns.
If you require any of these features, remember that you are free to mix and match muxes at any part of the stack.
In order to provide a sane API, many functions on Mux take interface{}'s. This is obviously not a very satisfying solution, but it's probably the best we can do for now. Instead of duplicating documentation on each method, the types accepted by those functions are documented here.
A middleware (the untyped parameter in Use() and Insert()) must be one of the following types:
- func(http.Handler) http.Handler
- func(c *web.C, http.Handler) http.Handler
All of the route-adding functions on Mux take two untyped parameters: pattern and handler. Pattern will be passed to ParsePattern, which takes a web.Pattern, a string, or a regular expression (more information can be found in the ParsePattern documentation). Handler must be one of the following types:
- http.Handler
- web.Handler
- func(w http.ResponseWriter, r *http.Request)
- func(c web.C, w http.ResponseWriter, r *http.Request)
func (*Mux) Abandon ¶
Remove the given middleware from the middleware stack. Returns an error if no such middleware can be found.
If the name of the middleware to delete is ambiguous, the first (outermost) one is chosen. It is illegal to call this function concurrently with active requests.
func (*Mux) Compile ¶
func (m *Mux) Compile()
Compile the list of routes into bytecode. This only needs to be done once after all the routes have been added, and will be called automatically for you (at some performance cost on the first request) if you do not call it explicitly.
func (*Mux) Connect ¶
func (m *Mux) Connect(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is CONNECT. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) Delete ¶
func (m *Mux) Delete(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is DELETE. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) Get ¶
func (m *Mux) Get(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is GET. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
All GET handlers also transparently serve HEAD requests, since net/http will take care of all the fiddly bits for you. If you wish to provide an alternate implementation of HEAD, you should add a handler explicitly and place it above your GET handler.
func (*Mux) Handle ¶
func (m *Mux) Handle(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches, regardless of HTTP method. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
This method is commonly used to implement sub-routing: an admin application, for instance, can expose a single handler that is attached to the main Mux by calling Handle("/admin*", adminHandler) or similar. Note that this function doesn't strip this prefix from the path before forwarding it on (e.g., the handler will see the full path, including the "/admin" part), but this functionality can easily be performed by an extra middleware layer.
func (*Mux) Head ¶
func (m *Mux) Head(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is HEAD. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) Insert ¶
Insert the given middleware immediately before a given existing middleware in the stack. See the documentation for type Mux for a list of valid middleware types. Returns an error if no middleware has the name given by "before."
No attempt is made to enforce the uniqueness of middlewares. If the insertion point is ambiguous, the first (outermost) one is chosen. It is illegal to call this function concurrently with active requests.
func (*Mux) NotFound ¶
func (m *Mux) NotFound(handler interface{})
Set the fallback (i.e., 404) handler for this mux. See the documentation for type Mux for a description of what types are accepted for handler.
As a convenience, the context environment variable "goji.web.validMethods" (also available as the constant ValidMethodsKey) will be set to the list of HTTP methods that could have been routed had they been provided on an otherwise identical request.
func (*Mux) Options ¶
func (m *Mux) Options(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is OPTIONS. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) Patch ¶
func (m *Mux) Patch(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is PATCH. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) Post ¶
func (m *Mux) Post(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is POST. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) Put ¶
func (m *Mux) Put(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is PUT. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) ServeHTTP ¶
func (m *Mux) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP processes HTTP requests. It make Muxes satisfy net/http.Handler.
func (*Mux) ServeHTTPC ¶
ServeHTTPC creates a context dependent request with the given Mux. Satisfies the web.Handler interface.
func (*Mux) Trace ¶
func (m *Mux) Trace(pattern interface{}, handler interface{})
Dispatch to the given handler when the pattern matches and the HTTP method is TRACE. See the documentation for type Mux for a description of what types are accepted for pattern and handler.
func (*Mux) Use ¶
func (m *Mux) Use(middleware interface{})
Append the given middleware to the middleware stack. See the documentation for type Mux for a list of valid middleware types.
No attempt is made to enforce the uniqueness of middlewares. It is illegal to call this function concurrently with active requests.
type Pattern ¶
type Pattern interface { // In practice, most real-world routes have a string prefix that can be // used to quickly determine if a pattern is an eligible match. The // router uses the result of this function to optimize away calls to the // full Match function, which is likely much more expensive to compute. // If your Pattern does not support prefixes, this function should // return the empty string. Prefix() string // Returns true if the request satisfies the pattern. This function is // free to examine both the request and the context to make this // decision. Match should not modify either argument, and since it will // potentially be called several times over the course of matching a // request, it should be reasonably efficient. Match(r *http.Request, c *C) bool // Run the pattern on the request and context, modifying the context as // necessary to bind URL parameters or other parsed state. Run(r *http.Request, c *C) }
A Pattern determines whether or not a given request matches some criteria. They are often used in routes, which are essentially (pattern, methodSet, handler) tuples. If the method and pattern match, the given handler is used.
Built-in implementations of this interface are used to implement regular expression and string matching.
func ParsePattern ¶ added in v0.8.2
func ParsePattern(raw interface{}) Pattern
ParsePattern is used internally by Goji to parse route patterns. It is exposed publicly to make it easier to write thin wrappers around the built-in Pattern implementations.
Although its parameter has type interface{}, ParsePattern only accepts arguments of three types:
- web.Pattern, which is passed through
- string, which is interpreted as a Sinatra-like URL pattern. In particular, the following syntax is recognized:
- a path segment starting with with a colon will match any string placed at that position. e.g., "/:name" will match "/carl", binding "name" to "carl".
- a pattern ending with "/*" will match any route with that prefix. For instance, the pattern "/u/:name/*" will match "/u/carl/" and "/u/carl/projects/123", but not "/u/carl" (because there is no trailing slash). In addition to any names bound in the pattern, the special key "*" is bound to the unmatched tail of the match, but including the leading "/". So for the two matching examples above, "*" would be bound to "/" and "/projects/123" respectively.
- regexp.Regexp, which is assumed to be a Perl-style regular expression that is anchored on the left (i.e., the beginning of the string). If your regular expression is not anchored on the left, a hopefully-identical left-anchored regular expression will be created and used instead. Named capturing groups will bind URLParams of the same name; unnamed capturing groups will be bound to the variables "$1", "$2", etc.
ParsePattern fatally exits (using log.Fatalf) if it is passed a value of an unexpected type. It is the caller's responsibility to ensure that ParsePattern is called in a type-safe manner.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package middleware provides several standard middleware implementations.
|
Package middleware provides several standard middleware implementations. |
Package mutil contains various functions that are helpful when writing http middleware.
|
Package mutil contains various functions that are helpful when writing http middleware. |