What does HackerNews think of httprouter?

A high performance HTTP request router that scales well

Language: Go

#3 in Go
#2 in Go
#1 in HTTP
I wonder if the new version takes the opportunity to make the muxer faster. I needed a path matcher / muxer and I settled on forking julienschmidt/httprouter [1] into my own project, pathmatcher [2]. What I like about the original it is that it uses a trie for mapping paths to handlers, which can look up routes very quickly [3], and is optimized for low/zero allocations. My changes generalizes it (the 'handler' value can be any generic type) and exposes the underlying data structure so you can do non-http.Handler things with it if you want.

[1]: https://github.com/julienschmidt/httprouter

[2]: https://github.com/infogulch/pathmatcher

[3]: https://github.com/julienschmidt/go-http-routing-benchmark

At a previous job we did a 'tech experiment' to write a Go REST service. As far as I'm aware it's still in use in a production-level capacity. It used the following:

- gotest

- No DI, but in hindsight this would have been the right thing to do. The dev team is 100% Python, so mocking was more the talk of the office than DI/IoC.

- For routing and HTTP the service used httprouter https://github.com/julienschmidt/httprouter

I think it's a fantastic language, gofmt and gotest are both great utilities, and the short time to create an executable made development turnaround a breeze.

However, I think for the purposes of a simple REST service I would probably use Python/Flask. Less boilerplate and for a Python team, it would have made more sense ...

Or if you can live with slightly fewer features (and an additional param for your handlers): https://github.com/julienschmidt/httprouter

Appears to be faster, but I guess the difference wouldn't be noticeable until you start doing some pretty heavy stuff.

After building apps in Martini and Revel, I’ve moved to using a smattering of decent (IMHO) packages good at 1 thing:

Let me render templates in a layout file with `yield` - https://github.com/unrolled/render

Let me quickly route with param support - https://github.com/julienschmidt/httprouter

Sessions, flash messages, and secure cookies - http://www.gorillatoolkit.org/pkg/sessions

POST parameter-to-structure binding (this is optional and easy enough to do by hand) - https://github.com/mholt/binding

I write my own middlewares for logging, auth, etc. Use viper for configuration, gorm for an ORM, and for anything more complicated, accept that you’re about to learn a whole lot about it because you’re gonna be writing it yourself.

gin[1] is a popular off-the-shelf solution that provides a lot of functionality for you. But as everdev said, it's pretty normal to gradually build up your own stack using the stdlib and possibly some smaller, more focused packages like httprouter[2] and the gorilla toolkit[3].

I actually have learned a lot about HTTP/HTTPS servers by working on a lower level and building up my stack! I recommend just starting with the stdlib and importing 3rd party code where you feel yourself limited by it. The first thing people probably adopt is a more expressive router.

[1] https://github.com/gin-gonic/gin

[2] https://github.com/julienschmidt/httprouter

[3] https://github.com/gorilla

In my opinion, it's great for web app backends as well. The net/http library suffices.

Just that you might need a library for routing like https://github.com/julienschmidt/httprouter

Rather than use a full-fledged framework, I would recommend combining orthogonal packages such as

- julienschmidt/httprouter [1] for routing,

- jmoiron/sqlx [2] for SQL access, and

- gorilla/websocket [3] for websockets

sqlx isn't an ORM; it's more a convenience wrapper around the standard library's database/sql package.

gorm is the nicest ORM I've found, but I think even the well-written ORM packages are unnatural to use because of restrictions in Go's type system.

(Sorry if this isn't the kind of answer you were hoping for.)

[1] https://github.com/julienschmidt/httprouter

[2] https://github.com/jmoiron/sqlx

[3] https://github.com/gorilla/websocket

Features

- Effective and flexible middlewares flow control, create anything by middleware

- Powerful and smart error handler, make development easy

- Trie base gear.Router, it is as faster as [HttpRouter](https://github.com/julienschmidt/httprouter), but more powerful

- Integrated timeout context.Context

- Integrated response content compress

- Integrated structured logging middleware

- Integrated request body parser

- Integrated signed cookies

- Integrated JSON, JSONP, XML and HTML renderer

- Integrated CORS, Secure, Favicon and Static middlewares

- More useful methods on gear.Context to manipulate HTTP Request/Response

- Completely HTTP/2.0 supported

I suggest you adopt a 3rd party router, rather than using pure Go standard library for this. https://github.com/julienschmidt/httprouter is the most popular one. It supports a custom 404 handler https://github.com/julienschmidt/httprouter/blob/master/rout...
Gorilla mux is way overrated and overused. I'm not sure why it's the first choice for so many people. There are much better alternatives such as https://github.com/julienschmidt/httprouter or https://github.com/gin-gonic/gin.
The first thing people tend to do is to replace the default, very primitive "mux" with a router that more closely aligns with modern expectations, such as httprouter (https://github.com/julienschmidt/httprouter) or chi (https://github.com/pressly/chi).

These libraries also support middleware wrapping [1], a technique that the default mux supports but doesn't help you with. For example, adding CORS headers or logging the request.

[1] https://justinas.org/writing-http-middleware-in-go/

Parts of the readme are copied from [0] julienschmidt/httprouter...

"In contrast to the default mux of Go's net/http package, this router supports variables in the routing pattern and matches against the request method. It also scales better."

[0] https://github.com/julienschmidt/httprouter

Does it use a trie? If not, it probably should. Here's a wonderful talk on using that datastructure (with go) for the gov uk url router:

https://gdstechnology.blog.gov.uk/2013/12/05/building-a-new-...

The Vulcan proxy from Mailgun does the same thing:

http://vulcand.github.io/proxy.html#route

It looks like it doesn't, so existing open source golang url routers will perform much better, contrary to this post. The one in vuland is interesting in that it supports both regex AND tries, so you get the best of both.

Additionally, httprouter (golang) uses a trie and is fast as hell:

https://github.com/julienschmidt/httprouter

Edit: Adding another one (thanks buro9!) that is used in production by CloudFlare:

https://github.com/pressly/chi

Gin uses HttpRouter (https://github.com/julienschmidt/httprouter) which is heavily optimized for performance, as can seen here: https://github.com/julienschmidt/go-http-routing-benchmark. As the author has noted on the page that "a comparison with other frameworks is coming soon" personally I would play safe and stick with HttpRouter for now and if it makes sense rewrite routing and switch to Lion once the performance characteristics are available.

(Or maybe the author, also the OP, could join and tell how Lion compares to HttpRouter)

I've found the standard library to be more than capable for most CRUD style apps. You can add in simple middleware chaining using a library such as Alice (https://github.com/justinas/alice) and for passing around request contexts between them, you can use something like xhandler (https://github.com/rs/xhandler). If you want more performant or flexible routing, httprouter (https://github.com/julienschmidt/httprouter) has a nice feature set.

Maybe it's personal preference, but there's something more satisfying about the modular approach of building up an app using only components I need and understand, rather than starting with a magical feature-laden framework but quickly realizing you don't need half of what it does. I think Go aligns particularly well with this philosophy given its emphasis on composition.

We're using either Gin[0] or pure net/http with Julian Schmidt's HttpRouter[1]. Even Gin lives on top of net/http, and most serious routers/frameworks do.

[0] https://github.com/gin-gonic/gin

[1] https://github.com/julienschmidt/httprouter

Interesting approach. I guess there are use cases where the small number of allocs of some of the other routers is enough to cause problems.

I'll definitely stick to httprouter as my default starting point, though. The params interface is much nicer, and it's pretty damn good with performance and allocation count: https://github.com/julienschmidt/httprouter

For the routing side of things, HttpRouter[0] seems like a nice alternative when performance matters to you. But as the author of this post referred to, sticking with the basics is a nice way to go. The nice thing about a lot of these frameworks, is that you can use bits and pieces of them if you'd like, you aren't required to use all the functionality.

[0] https://github.com/julienschmidt/httprouter

About this part in README:

> I have very little interest in boosting Goji's router's benchmark scores. There is an obvious solution here--radix trees--and maybe if I get bored I'll implement one for Goji, but I think the API guarantees and conceptual simplicity Goji provides are more important (all routes are attempted, one after another, until a matching route is found). Even if I choose to optimize Goji's router, Goji's routing semantics will not change.

Maybe you can just use HttpRouter without reimplementing it yourself?

https://github.com/julienschmidt/httprouter

> The router is optimized for best performance and a small memory footprint. It scales well even with very long pathes and a large number of routes. A compressing dynamic trie (radix tree) structure is used for efficient matching.

    goji.Get("/hello/:name", hello)

    router := httprouter.New()
    router.GET("/hello/:name", Hello)