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/httprouteris 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 handlesOPTIONSrequests and sends405responses correctly, and allows you to set custom handlers for404and405responses too.go-chi/chiis generally similar tohttprouterin 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
chiare that it doesn’t automatically handleOPTIONSrequests, and it doesn’t set anAllowheader in405responses.gorilla/muxis 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 handleOPTIONSrequests, and it doesn’t set anAllowheader in405responses.
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.