Flow: A delightfully tiny but powerful HTTP router for Go
Last year I wrote a new HTTP router for Go called Flow
. I've been using it in production on this site and in a couple of other projects since, and I'm pretty happy with how it's working out so decided to share it a bit more widely.
My aim with Flow
was to bring together my favourite features from other popular routers that I frequently used. It has:
- A very small and readable codebase (approx. 160 LOC) with pattern-matching logic similar to
matryer/way
. - Middleware management like
chi
— including the ability to create route 'groups' which use different middleware. - Optional regexp support for tighter pattern matching, similar to
chi
andgorilla/mux
. - Automatic handling of
OPTIONS
requests, likejulienschmidt/httprouter
. - Automatic handling of
HEAD
requests, likebmizerany/pat
. - An
Allow
header is automatically set on allOPTIONS
and405 Method Not Allowed
responses, likejulienschmidt/httprouter
. - Ability to map multiple HTTP methods to the same handler in one declaration, like
gorilla/mux
.
Additionally:
- It has a very small API (see the Go docs) so there's not much to learn.
- It's designed to work nicely with
http.Handler
,http.HandlerFunc
, and the standard Go middleware pattern. - The handlers for
404 Not Found
and405 Method Not Allowed
responses are customizable. - Conflicting routes are permitted (e.g.
/posts/:id
andposts/new
), with routes matched in the order that they are declared. - It has zero dependencies.
Below is a quick example of the syntax, and if you like the look of it you can check out the full README on GitHub.
A note on performance
I haven't done any benchmarking against other routers, so I can't speak about the relative performance of Flow
. What I can say it has been plenty fast enough for all of my use-cases so far and not a hot spot when profiling my applications under load.