Conversation
| Options(pattern string, handlers ...interface{}) | ||
| Use(middlewares ...func(http.Handler) http.Handler) | ||
| Stack(fn func(r Router)) Router | ||
| Group(pattern string, fn func(r Router)) Router |
There was a problem hiding this comment.
pkieltyka commented 6 days ago
btw, what do you guys think about 3c613e2 ? for chi v2, I believe the names Group() and Stack() reflect better the intention of the methods. That is, to group routes by a routing pattern and to stack one router ontop of another without a pattern.
There was a problem hiding this comment.
To be honest, I like the original r.Route("/route", subrouter) and r.Group(subrouter) better. Stack() sounds confusing to me, since it doesn't really trigger "custom middleware stack" in my head. And I'm not huge fan of changing .Group() logic either.
There was a problem hiding this comment.
btw: How about removing .Route(), changing .Mount()'s signature (so it's not like .Handle()) and keep .Group() only?
type Router interface {
http.Handler
Group(fn func(r Router)) Router
Mount(pattern string, r Router)
Handle(pattern string, h http.Handler)
//...
}
// --------
r := chi.NewRouter()
r.Use(ForAllCtx)
r.Group(func(r chi.Router) {
r.Use(SpecialCtx)
r.Get("/", handler)
})
r.Mount("/ping", subrouter)
r.Mount("/:articleID", r.Group(func(r chi.Router) {
r.Use(ArticleCtx)
r.Get("/", getArticle)
}))There was a problem hiding this comment.
I think you're right and I'll go back to original Route() and Group() for now
Route is like a Mount that accepts a function instead of the router, I like it for building the tree as shorthand
On Jun 15, 2016, at 11:32 PM, Vojtech Vitek notifications@github.com wrote:
In chi.go:
- Connect(pattern string, handlers ...interface{})
- Head(pattern string, handlers ...interface{})
- Get(pattern string, handlers ...interface{})
- Post(pattern string, handlers ...interface{})
- Put(pattern string, handlers ...interface{})
- Patch(pattern string, handlers ...interface{})
- Delete(pattern string, handlers ...interface{})
- Trace(pattern string, handlers ...interface{})
- Options(pattern string, handlers ...interface{})
- Use(middlewares ...func(http.Handler) http.Handler)
- Stack(fn func(r Router)) Router
- Group(pattern string, fn func(r Router)) Router
btw: How about removing .Route(), changing .Mount() signature (so it's not like .Handle()) and keep .Group() only?type Router interface {
http.HandlerGroup(fn func(r Router)) Router Mount(pattern string, r Router) Handle(pattern string, h http.Handler) //...}
// --------
r := chi.NewRouter()
r.Use(ForAllCtx)r.Group(func(r chi.Router) {
r.Use(SpecialCtx)
r.Get("/", handler)
})r.Mount("/ping", subrouter)
r.Mount("/:articleID", r.Group(func(r chi.Router) {
r.Use(ArticleCtx)
r.Get("/", getArticle)
}))
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
| Group(pattern string, fn func(r Router)) Router | ||
| Mount(pattern string, h http.Handler) // TODO: mount a Router instead of http.Handler? | ||
|
|
||
| Handle(pattern string, h http.Handler) |
There was a problem hiding this comment.
IMO it should be
Handle(method, pattern string, h http.Handler)
All(pattern string, h http.Handler)First All (or Any) is more self-explanatory, second method set can be extended. Not just "can be extended in theory" but this is something that is frequently done when building a protocol on top of HTTP - see WEBDAV for example.
There was a problem hiding this comment.
Supporting this would also require a change to treeRouter.route to use string as key.
OR, which I believe is better
have a single route on treeRouter & have map[method]http.Handler on node
Benefits:
- single route tree, instead of multiple (you are adding chain to ALL method trees on .Route now)
- extensible method list
- proper HTTP 405 handling (we're returning 404 when there is a route, just not for current method, which is incorrect - 404 should be returned when there is no route for ANY method)
- no pointers in the tree -> no indirects -> routing tree as a single object and will often fit entirely in CPU cache (vs cache miss on every routing level - 2-5 CPU cycles vs 200-400 - see the very first table in https://blog.codinghorror.com/the-infinite-space-between-words/ )
, instead of having a route[method]*treeRouter in a tree
Master merge into V2
Conflicts: middleware/strip.go mux.go
v2: Render + Presenter
|
We have a chi based reverse proxy serving ~12M requests a day. It has a lot of http.Handler middleware so there were many layers of 'mwrap' on our requests. I updated to golang 1.7 and this branch to see how the benchmarks would look: Approaching +30%! I'm excited to see the real-world performance. |
|
|
||
| // Register routing handler for GET http method | ||
| Get(pattern string, handlers ...interface{}) | ||
| Get(pattern string, handler http.HandlerFunc) |
There was a problem hiding this comment.
I cant see a way to mount a GET/POST/PUT only http.Handler, short of wrapping it in a:
r.Get("/foo", func(w http.ResponseWriter, r *http.Request) {
handler.ServeHttp(w, r)
})Perhaps these should be http.Handler?
There was a problem hiding this comment.
Yeah seconded - there is Handle and HandleFunc, should there also be Get and GetFunc?
Targeting the interface imposes less opinions on usage.
There was a problem hiding this comment.
@vektah great to hear! chi v2 doesn't need mwrap anymore :)
http.HandlerFunc provides us the most flexibility while keeping the chi.Router interface succinct and clean. You can write:
r.Get("/foo", handler.ServeHTTP)|
@vektah thanks for the interesting benchmark results! |
| We've designed the Pressly API (150+ routes/handlers) exactly like this for the goals of productivity, | ||
| maintainability and expression. | ||
|
|
||
|  |
There was a problem hiding this comment.
@pkieltyka Instead of this chi photo, we should show a simple usage example or benchmarks.

Opening PR from @pkieltyka's WIP v2 branch, so we can discuss final chi v2 features and push this forward :)
btw: Big kudos to @pkieltyka for opening discussion about having "context" in golang stdlib http pkg in the first place: