Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/naoina/denco
The fast and flexible HTTP request router for Go
https://github.com/naoina/denco
Last synced: 3 months ago
JSON representation
The fast and flexible HTTP request router for Go
- Host: GitHub
- URL: https://github.com/naoina/denco
- Owner: naoina
- License: mit
- Created: 2014-06-06T05:25:46.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2018-09-30T07:49:28.000Z (over 6 years ago)
- Last Synced: 2024-08-03T13:14:42.528Z (6 months ago)
- Language: Go
- Homepage:
- Size: 42 KB
- Stars: 225
- Watchers: 7
- Forks: 24
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-go - denco - The fast and flexible HTTP request router (Multiplexers)
README
# Denco [![Build Status](https://travis-ci.org/naoina/denco.png?branch=master)](https://travis-ci.org/naoina/denco)
The fast and flexible HTTP request router for [Go](http://golang.org).
Denco is based on Double-Array implementation of [Kocha-urlrouter](https://github.com/naoina/kocha-urlrouter).
However, Denco is optimized and some features added.## Features
* Fast (See [go-http-routing-benchmark](https://github.com/naoina/go-http-routing-benchmark))
* [URL patterns](#url-patterns) (`/foo/:bar` and `/foo/*wildcard`)
* Small (but enough) URL router API
* HTTP request multiplexer like `http.ServeMux`## Installation
go get -u github.com/naoina/denco
## Using as HTTP request multiplexer
```go
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))
}
```## Using as URL router
```go
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](http://godoc.org/github.com/naoina/denco) for more details.
## Getting the value of path parameter
You can get the value of path parameter by 2 ways.
1. Using [`denco.Params.Get`](http://godoc.org/github.com/naoina/denco#Params.Get) method
2. Find by loop```go
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.".
}
}
}
```## URL patterns
Denco's route matching strategy is "most nearly matching".
When routes `/:name` and `/alice` have been built, URI `/alice` matches the route `/alice`, not `/:name`.
Because URI `/alice` is more match with the route `/alice` than `/: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")
```## Limitation
Denco has some limitations below.
* Number of param records (such as `/:name`) must be less than 2^22
* Number of elements of internal slice must be less than 2^22## Benchmarks
cd $GOPATH/github.com/naoina/denco
go test -bench . -benchmem## License
Denco is licensed under the MIT License.