mirror of
https://github.com/go-gitea/gitea
synced 2024-09-12 14:56:05 +00:00
* Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net>
181 lines
4.6 KiB
Markdown
181 lines
4.6 KiB
Markdown
# 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/go-openapi/runtime/middleware/denco
|
|
|
|
## Using as HTTP request multiplexer
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
|
|
"github.com/go-openapi/runtime/middleware/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 main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/go-openapi/runtime/middleware/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/go-openapi/runtime/middleware/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/go-openapi/runtime/middleware/denco#Params.Get) method
|
|
2. Find by loop
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/go-openapi/runtime/middleware/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/go-openapi/runtime/middleware/denco
|
|
go test -bench . -benchmem
|
|
|
|
## License
|
|
|
|
Denco is licensed under the MIT License.
|