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 Found
and 405 Method Not Allowed
responses. - Automatic handling of
OPTIONS
and HEAD
requests. - Works with
http.Handler
, http.HandlerFunc
, and standard Go middleware. - Zero dependencies.
- Tiny, readable, codebase (~160 lines of code).
Installation
$ go get github.com/alexedwards/flow@latest
Basic example
package main
import (
"fmt"
"log"
"net/http"
"github.com/alexedwards/flow"
)
func main() {
mux := flow.New()
mux.HandleFunc("/greet/:name", greet, "GET")
err := http.ListenAndServe(":2323", mux)
log.Fatal(err)
}
func greet(w http.ResponseWriter, r *http.Request) {
name := flow.Param(r.Context(), "name")
fmt.Fprintf(w, "Hello %s", name)
}
Kitchen-sink example
mux := flow.New()
mux.Use(exampleMiddleware1)
mux.HandleFunc("/profile/:name", exampleHandlerFunc1, "GET", "POST")
mux.HandleFunc("/profile/:name/:age|^[0-9]{1,3}$", exampleHandlerFunc2, "GET")
mux.Handle("/static/...", exampleHandler)
mux.Group(func(mux *flow.Mux) {
mux.Use(exampleMiddleware2)
mux.HandleFunc("/admin", exampleHandlerFunc3, "GET")
mux.Group(func(mux *flow.Mux) {
mux.Use(exampleMiddleware3)
mux.HandleFunc("/admin/passwords", exampleHandlerFunc4, "GET")
})
})
Notes
- Conflicting routes are permitted (e.g.
/posts/:id
and posts/new
). Routes are matched in the order that they are declared. - Trailing slashes are significant (
/profile/:id
and /profile/:id/
are not the same). - An
Allow
header is automatically set for all OPTIONS
and 405 Method Not Allowed
responses (including when using custom handlers). - Once the
flow.Mux
type 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", ...)
mux.Use(middleware2)
mux.HandleFunc("/bar", ...)
Contributing
Bug fixes and documentation improvements are very welcome! For feature additions or behavioral changes, please open an issue to discuss the change before submitting a PR.
Thanks
The pattern matching logic for Flow was heavily inspired by matryer/way.