Choosing a router
There a literally hundreds of third-party routers for Go to pick from. And (fortunately or unfortunately, depending on your perspective) they all work a bit differently. They have different APIs, different logic for matching routes, and different behavioral quirks.
Out of all the third-party routers I’ve tried there are three that I recommend as a starting point: julienschmidt/httprouter
, go-chi/chi
and gorilla/mux
. They all have good documentation, decent test coverage, and work well with the standard patterns for handlers and middleware that we’ve used in this book.
All three routers also support method-based routing and clean URLs, but beyond that they have slightly different behaviors and features. You should pick between them depending on the specific requirements that your project has.
In summary:
julienschmidt/httprouter
is the most focused, lightweight and fastest of the three packages, and is about as close to ‘perfect’ as any third-party router gets in terms of its compliance with the HTTP specs. It automatically handlesOPTIONS
requests and sends405
responses correctly, and allows you to set custom handlers for404
and405
responses too.go-chi/chi
is generally similar tohttprouter
in terms of its features, with the main differences being that it also supports regexp route patterns and ‘grouping’ of routes which use specific middleware. This route grouping feature is really valuable in larger applications where you have lots routes and middleware to manage.Two downsides of
chi
are that it doesn’t automatically handleOPTIONS
requests, and it doesn’t set anAllow
header in405
responses.gorilla/mux
is the most full-featured of the three routers. It supports regexp route patterns, and allows you to route requests based on scheme, host and headers. It’s also the only one to support custom routing rules and route ‘reversing’ (like you get in Django, Rails or Laravel).There are two main downsides of
gorilla/mux
. The first downside is that the project is no longer actively maintained and is in archive mode on GitHub. That doesn’t necessarily mean you should avoid it — the code is stable and battle-hardened, and due to the Go compatibility promise it’s likely to remain working without problems for many versions of Go to come. However any bugs, if they do arise, won’t be fixed in the package.The other downside is that it’s comparatively slow and memory hungry — although for a database-driven web application like ours the impact over the lifetime of a whole HTTP request is likely to be small. Like
chi
, it also doesn’t automatically handleOPTIONS
requests, and it doesn’t set anAllow
header in405
responses.
In our case, our application is fairly small and we don’t need support for anything beyond basic method-based routing and clean URLs. So, for the sake of performance and correctness, we’ll opt to use julienschmidt/httprouter
in this project.