The fast and flexible HTTP request router for Go
The fast and flexible HTTP request router for Go.
Denco is based on Double-Array implementation of Kocha-urlrouter. However, Denco is optimized and some features added.
/foo/:barand
/foo/*wildcard)
http.ServeMux
go get -u github.com/naoina/denco
package mainimport ( "fmt" "log" "net/http"
"github.com/naoina/denco"
)
func Index(w http.ResponseWriter, r *http.Request, params denco.Params) { fmt.Fprintf(w, "Welcome to Denco!\n") }
func User(w http.ResponseWriter, r *http.Request, params denco.Params) { fmt.Fprintf(w, "Hello %s!\n", params.Get("name")) }
func main() { mux := denco.NewMux() handler, err := mux.Build([]denco.Handler{ mux.GET("/", Index), mux.GET("/user/:name", User), mux.POST("/user/:name", User), }) if err != nil { panic(err) } log.Fatal(http.ListenAndServe(":8080", handler)) }
package mainimport ( "fmt"
"github.com/naoina/denco"
)
type route struct { name string }
func main() { router := denco.New() router.Build([]denco.Record{ {"/", &route{"root"}}, {"/user/:id", &route{"user"}}, {"/user/:name/:id", &route{"username"}}, {"/static/*filepath", &route{"static"}}, })
data, params, found := router.Lookup("/") // print `&main.route{name:"root"}, denco.Params(nil), true`. fmt.Printf("%#v, %#v, %#v\n", data, params, found) data, params, found = router.Lookup("/user/hoge") // print `&main.route{name:"user"}, denco.Params{denco.Param{Name:"id", Value:"hoge"}}, true`. fmt.Printf("%#v, %#v, %#v\n", data, params, found) data, params, found = router.Lookup("/user/hoge/7") // print `&main.route{name:"username"}, denco.Params{denco.Param{Name:"name", Value:"hoge"}, denco.Param{Name:"id", Value:"7"}}, true`. fmt.Printf("%#v, %#v, %#v\n", data, params, found) data, params, found = router.Lookup("/static/path/to/file") // print `&main.route{name:"static"}, denco.Params{denco.Param{Name:"filepath", Value:"path/to/file"}}, true`. fmt.Printf("%#v, %#v, %#v\n", data, params, found)
}
See Godoc for more details.
You can get the value of path parameter by 2 ways.
denco.Params.Getmethod
package mainimport ( "fmt"
"github.com/naoina/denco"
)
func main() { router := denco.New() if err := router.Build([]denco.Record{ {"/user/:name/:id", "route1"}, }); err != nil { panic(err) }
// 1. Using denco.Params.Get method. _, params, _ := router.Lookup("/user/alice/1") name := params.Get("name") if name != "" { fmt.Printf("Hello %s.\n", name) // prints "Hello alice.". } // 2. Find by loop. for _, param := range params { if param.Name == "name" { fmt.Printf("Hello %s.\n", name) // prints "Hello alice.". } }
}
Denco's route matching strategy is "most nearly matching".
When routes
/:nameand
/alicehave been built, URI
/alicematches the route
/alice, not
/:name. Because URI
/aliceis more match with the route
/alicethan
/:name.
For more example, when routes below have been built:
/user/alice /user/:name /user/:name/:id /user/alice/:id /user/:id/bob
Routes matching are:
/user/alice => "/user/alice" (no match with "/user/:name") /user/bob => "/user/:name" /user/naoina/1 => "/user/:name/1" /user/alice/1 => "/user/alice/:id" (no match with "/user/:name/:id") /user/1/bob => "/user/:id/bob" (no match with "/user/:name/:id") /user/alice/bob => "/user/alice/:id" (no match with "/user/:name/:id" and "/user/:id/bob")
Denco has some limitations below.
/:name) must be less than 2^22
cd $GOPATH/github.com/naoina/denco go test -bench . -benchmem
Denco is licensed under the MIT License.