Package gorilla/muxy takes gorilla/mux to the next level.
This is a work in progress: not stable, not usable etc.
Package gorilla/muxy takes gorilla/mux to the next level
Home Page: https://gorilla.github.io
License: BSD 3-Clause "New" or "Revised" License
Here are some initial benchmarks comparing gorilla/mux, httprouter and gorilla/muxy.
Note: muxy is not even done with optimizations yet, and specially no static matching optimizations were applied so far (I have a plan for them).
Matching with 1 variable
gorilla/mux 200000 6650 ns/op 832 B/op 11 allocs/op
httprouter 5000000 278 ns/op 32 B/op 1 allocs/op
gorilla/muxy 10000000 220 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Matching with 5 variables
gorilla/mux 100000 12260 ns/op 1088 B/op 19 allocs/op
httprouter 2000000 718 ns/op 160 B/op 1 allocs/op
gorilla/muxy 3000000 463 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Matching with 20 variables
gorilla/mux 50000 29081 ns/op 3931 B/op 51 allocs/op
httprouter 1000000 2065 ns/op 640 B/op 1 allocs/op
gorilla/muxy 1000000 1616 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Matching all static
gorilla/mux 500 3632207 ns/op 71520 B/op 1192 allocs/op
httprouter 50000 30321 ns/op 0 B/op 0 allocs/op
gorilla/muxy 30000 50069 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
GitHub API - Matching with variables
gorilla/mux 100000 25261 ns/op 896 B/op 13 allocs/op
httprouter 2000000 639 ns/op 96 B/op 1 allocs/op
gorilla/muxy 3000000 459 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
GitHub API - Matching static
gorilla/mux 50000 35582 ns/op 480 B/op 8 allocs/op
httprouter 20000000 123 ns/op 0 B/op 0 allocs/op
gorilla/muxy 10000000 174 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
GitHub API - Matching all
gorilla/mux 100 13680783 ns/op 167232 B/op 2469 allocs/op
httprouter 10000 118606 ns/op 13792 B/op 167 allocs/op
gorilla/muxy 20000 101905 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Google Plus API - Matching with 1 variable
gorilla/mux 200000 9200 ns/op 832 B/op 11 allocs/op
httprouter 3000000 458 ns/op 64 B/op 1 allocs/op
gorilla/muxy 5000000 241 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Google Plus API - Matching with 2 variables
gorilla/mux 100000 20531 ns/op 896 B/op 13 allocs/op
httprouter 3000000 537 ns/op 64 B/op 1 allocs/op
gorilla/muxy 3000000 381 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Google Plus API - Matching static
gorilla/mux 500000 4070 ns/op 480 B/op 8 allocs/op
httprouter 20000000 69.4 ns/op 0 B/op 0 allocs/op
gorilla/muxy 10000000 117 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Google Plus API - Matching all
gorilla/mux 10000 148108 ns/op 10432 B/op 147 allocs/op
httprouter 300000 5983 ns/op 640 B/op 11 allocs/op
gorilla/muxy 300000 4140 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Parse API - Matching with 1 variable
gorilla/mux 200000 7645 ns/op 832 B/op 11 allocs/op
httprouter 3000000 406 ns/op 64 B/op 1 allocs/op
gorilla/muxy 5000000 305 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Parse API - Matching with 2 variables
gorilla/mux 200000 9020 ns/op 896 B/op 13 allocs/op
httprouter 3000000 459 ns/op 64 B/op 1 allocs/op
gorilla/muxy 3000000 376 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Parse API - Matching static
gorilla/mux 200000 6260 ns/op 480 B/op 8 allocs/op
httprouter 20000000 73.5 ns/op 0 B/op 0 allocs/op
gorilla/muxy 10000000 218 ns/op 0 B/op 0 allocs/op
---------------------------------------------------------------------------------------------
Parse API - Matching all
gorilla/mux 5000 284016 ns/op 18304 B/op 262 allocs/op
httprouter 200000 8605 ns/op 640 B/op 16 allocs/op
gorilla/muxy 200000 9465 ns/op 0 B/op 0 allocs/op
I detected two kinds of subrouting that we may want to support:
These are somewhat related. The first one is simply "nice to have"; the second is not a so common use case, but why not? In any case, the first can be used by the second when mounting a foreign router in a given path. The docs for Mount()
illustrate it better:
// Mount imports all routes from the given router into this one.
//
// Combined with Sub() and Name(), it is possible to submount a router
// defined in a different package using pattern and name prefixes:
//
// r := New()
// s := r.Sub("/admin").Name("admin:").Mount(admin.Router)
func (r *Router) Mount(router *Router) *Router {
These two kinds of subrouting require the three router methods exemplified in the docs above: Sub()
(which creates a subrouter for a pattern prefix), Name()
(sets a name prefix for the routes), and Mount()
(imports routes defined elsewhere).
Given this initial draft, I invite you to share your thoughts about the subject.
Might as well start this to pick up where gorilla/mux#130 leaves off.
Some high-level comments:
func (r *Route) Handler(handler http.HandlerFunc, methods ...string) *Route
should accept a http.Handler
and have a sister method HandleFunc
that accepts a http.HandleFunc
.Get
, Head
, etc. convenience methods—additional methods for these would clutter the API.router.Sub
return a *Router
instead, allowing you to use the same methods as you would on a *Router
? prefix
could be a field of Router that the call to router.Sub
sets.The title says it all: I'd like to hear your opinions about the pros and cons to stay with the func(http.ResponseWriter, *http.Request)
signature for handlers, and why not set one that accepts an extra variables parameter.
My time to code is very limited, so would anybody help transforming parse()
here into a real, efficient string parser?
http://play.golang.org/p/BPZ2KX6SsB
Sorry for the quick hack. 😔
https://tip.golang.org/doc/go1.7#context
Go 1.7's http.Request
now has a Context() context.Context
method. We can now rely on this to pass route/pattern/match information alongside a request and remove the need to use interface{}
for handling different handler signatures.
Major benefits:
http.Handler
interface{}
)e.g.
- func (r *Route) Get(h interface{}) *Route
+ func (r *Route) Get(h http.Handler) *Route
type Matcher interface {
...
- Match(c context.Context, r *http.Request) (context.Context, Handler)
+ Match(r *http.Request) (*http.Request, Handler)
...
}
- func Var(c context.Context, name string) string
+ func Var(r *http.Request, name string) string
gorilla/mux can continue to support older applications, and you could potentially use build tags to fall back to using gorilla/context
for <= Go 1.6 as I did with the csrf package: gorilla/csrf#35
@moraes - not sure on your thoughts here and/or whether you want to pick up work on this again.
Hi,
I would like to help with your development if it's possible and I've also been thinking, if it's worth having, concurrent middleware. If the middleware function returns a channel then it will be a concurrent middleware and the Handle will be executed when all concurrent middleware finished.
package main
import (
"io"
"net/http"
"github.com/gorilla/muxy"
)
func main() {
router := muxy.New()
router.Route("/{a}/{b}").Get(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "/{a}/{b}")
})
router.Route("/{a}/{b}/{c}").Get(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "/{a}/{b}/{c}")
})
http.ListenAndServe(":80", router)
}
/{a}/{b} match //
/{a}/{b}/{c} match ///
as expected?
Some questions to get the ball rolling on this:
Also take a look at what alice and negroni do—although I think the latter is too centered on its own HandlerFunc
type to be useful.
My thoughts:
func(http.Handler) http.Handler
has become the 'defacto' standard.Use(auth).Use(csrf).Use(logging)
is clunky and serves little benefit.router.Use(middleware ...func(http.Handler) http.Handler)
— keep it simple.Middleware should apply to all routes below it (no exceptions), and sub-routers (however they shake out) should be able to apply additional middleware (e.g. auth) of their own.
/{a}-{b}
/{a}_{b}
/{a}.{b}
/a{b}/{c}
router := muxy.New()
router.Route("/{*}").Get(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "/{*}")
})
router.Route("/{a}/{b}").Get(func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "/{a}/{b}")
})
http.ListenAndServe(":80", router)
/{a}/{b} match /a/b
/{*} mismatch /a
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.