Go Reference Go Report Card MIT Code size
A delightfully tiny but powerful HTTP router for Go web applications
Flow packs in a bunch of features that you'll probably like:
- Use named parameters, wildcards and (optionally) regexp patterns in your routes.
- Create route groups which use different middleware (a bit like chi).
- Customizable handlers for
404 Not Foundand405 Method Not Allowedresponses. - Automatic handling of
OPTIONSandHEADrequests. - Works with
http.Handler,http.HandlerFunc, and standard Go middleware. - Zero dependencies.
- Tiny, readable, codebase (~160 lines of code).
This package has reached a stable status. It is actively maintained with ongoing bug fixes and essential updates, and significant alterations to the API or behavior are not expected.
$ go get github.com/alexedwards/flow@latest
package main import ( "fmt" "log" "net/http" "github.com/alexedwards/flow" ) func main() { // Initialize a new router. mux := flow.New() // Add a `GET /greet/:name` route. The : character is used to denote a // named parameter in the URL path, which acts like a 'wildcard'. mux.HandleFunc("/greet/:name", greet, "GET") err := http.ListenAndServe(":2323", mux) log.Fatal(err) } func greet(w http.ResponseWriter, r *http.Request) { // Retrieve the value of the named parameter from the request. name := r.PathValue("name") fmt.Fprintf(w, "Hello %s", name) }
mux := flow.New() // The Use() method can be used to register middleware. Middleware declared at // the top level will be used on all routes (including error handlers and OPTIONS // responses). mux.Use(exampleMiddleware1) // Routes can use multiple HTTP methods. mux.HandleFunc("/profile/:name", exampleHandlerFunc1, "GET", "POST") // Optionally, regular expressions can be used to enforce a specific pattern // for a named parameter. mux.HandleFunc("/profile/:name/:age|^[0-9]{1,3}$", exampleHandlerFunc2, "GET") // The wildcard ... can be used to match the remainder of a request path. // Notice that HTTP methods are also optional (if not provided, all HTTP // methods will match the route). The value of the wildcard can be retrieved // by calling r.PathValue("..."). mux.Handle("/static/...", exampleHandler) // You can create route 'groups'. mux.Group(func(mux *flow.Mux) { // Middleware declared within the group will only be used on the routes // in the group. mux.Use(exampleMiddleware2) mux.HandleFunc("/admin", exampleHandlerFunc3, "GET") // Groups can be nested. mux.Group(func(mux *flow.Mux) { mux.Use(exampleMiddleware3) mux.HandleFunc("/admin/passwords", exampleHandlerFunc4, "GET") }) })
- Conflicting routes are permitted (e.g.
/posts/:idandposts/new). Routes are matched in the order that they are declared. - Trailing slashes are significant (
/profile/:idand/profile/:id/are not the same). - An
Allowheader is automatically set for allOPTIONSand405 Method Not Allowedresponses (including when using custom handlers). - Once the
flow.Muxtype is being used by your server, it is not safe to add more middleware or routes concurrently. - Middleware must be declared before a route in order to be used by that route. Any middleware declared after a route won't act on that route. For example:
mux := flow.New() mux.Use(middleware1) mux.HandleFunc("/foo", ...) // This route will use middleware1 only. mux.Use(middleware2) mux.HandleFunc("/bar", ...) // This route will use both middleware1 and middleware2.
The pattern matching logic for Flow was heavily inspired by matryer/way.