Notes on the httprouter Golang library
For most simple to moderately complex web servers in Golang, I have always preferred to use the standard net/http library, laboring through the parsing of RequestPaths and query parameters when necessary.
But when the boilerplate code for request parsing starts obscuring the business logic, I tend to look out at other libraries. I however have always hesitated using too heavy a framework to keep dependencies simple.
For HTTP routing, for example, I have found httprouter to satisfy most of the gaps in the standard library that I have frequently faced, and at the same time the library is totally dep free!
Here are some really quick notes about using the library, mostly for my own reference. 😄
CONTENTS:
Overview
- Github: https://github.com/julienschmidt/httprouter
- Godoc: https://godoc.org/github.com/julienschmidt/httprouter
This is a very minimalistic http router library which addresses the most frequently felt gaps in the standard library:
- http method specific handlers.
- Named parameters in the path.
The feature set is deliberately kept simple, and for users who want more, the author encourages them to use one of the many other libraries that have popped up wrapping this routing library.
Example Usage
Notes:
-
A route registration call specifies the HTTP method -
router.GET()
. -
The
Index()
andHello
handlers are not stdlib compatible and have an extra library specific parameter. -
The
Hello()
handler uses a named parameter retrieved inside the handler using the new third parameter in the handler. -
Calls to
/hello/xxx/yyy
will not be matched to/hello/:name
- the routing is explicit. -
You cannot add a static route overlapping the named parameter. e.g. You cannot now have a route for
/hello/somewhere
. That second path component is already taken by the route for/hello/:name
. -
As shown in the
Welcome()
handler, you can use a wildcard named parameter (e.g.*where
here) at the end of a routing pattern using a*
prefix to slurp up everything to the right of the URI. You can use a named parameter as many times as you want as well, but the wildcard one has to be at the end of the pattern - see (C).$ curl -s localhost:8888/welcome/sandip/to/wonderland/for/ever Welcome, sandip to to/wonderland/for/ever!
-
You can use a standard http handler too - see
Salut()
. To reach for the named parameters, you need to usehttprouter.ParamsFromContext()
helper function to retrieve the usual third parameter in the custom handlers, theParams
from the request context - see (A).However, note that the routing function is now a non-standard
router.HandlerFunc()
which expects the HTTP method name as the first parameter - see (B). -
You can provide an endpoint for static file serving using
ServeFiles()
- see (D).!!Note!! however that directory index display is enabled, so an empty file name can display directory contents.
$ curl -s 127.0.0.1:8888/files/ <pre> <a href="go.mod">go.mod</a> <a href="go.sum">go.sum</a> <a href="simple.go">simple.go</a> </pre>
Additional features
The router has some optional fields for provide default handling of specific exceptions:
router.Notfound
can be set to handle requests to paths which are not matched by any routing patterns.- Setting
router.HandleMethodNotAllowed
totrue
allows you to set a handler inrouter.MethodNotAllowed
to handle situations when a request has been sent to a router pattern which exists but with a different http verb. e.g. Only aGET
route exists but aPOST
verb was used in the request. - You can recover from panics in your server handlers by setting
router.PanicHandler
to an appropriate handler which can send a suitable 5xx error. - You can set CORS headers by setting
router.GlobalOPTIONS
to a suitable handler. The Godoc provides a code sample.
Credit: “Blue Gopher” icon by Ashley McNamara