A golang http router based on trie tree.
- Go 1.13
- Easy to use
- Lightweight
- Fully compatible with net/http
- No external dependencies
- Support named parameters with an optional regular expression.
go get -u github.com/bmf-san/goblin
goblin supports these http methods.
GET/POST/PUT/PATCH/DELETE/OPTION
You can define routing like this.
r := goblin.NewRouter()
r.GET(`/`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "/")
}))
r.POST(`/`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "/")
}))
You can use named parameters like this.
r := goblin.NewRouter()
r.GET(`/foo/:id`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := goblin.GetParam(r.Context(), "id")
fmt.Fprintf(w, "/foo/%v", id)
}))
r.POST(`/foo/:name`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
name := goblin.GetParam(r.Context(), "name")
fmt.Fprintf(w, "/foo/%v", name)
}))
You can also use named parameter with regular expression like this.
:paramName[pattern]
r.GET(`/foo/:id[^\d+$]`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := goblin.GetParam(r.Context(), "id")
fmt.Fprintf(w, "/foo/%v", id)
}))
Since the default pattern is (.+)
, if you don't define it, then :id
is defined as :id[(.+)]
.
A routing pattern matching priority depends on an order of routing definition.
r := goblin.NewRouter()
r.GET(`/foo/:id`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `/foo/:id`)
}))
r.GET(`/foo/:id[^\d+$]`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `/foo/:id[^\d+$]`)
}))
r.GET(`/foo/:id[^\w+$]`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `/foo/:id[^\w+$]`)
}))
If you want to define a route that matches anything, you can define it as follows.
r := goblin.NewRouter()
// This definition needs to be defined last for the most part. Otherwise, it will not match correctly.
// Incidentally, this can be used to deal with preflight.
r.OPTION(`:`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `: metches anything`)
}))
package main
import (
"fmt"
"net/http"
goblin "github.com/bmf-san/goblin"
)
func main() {
r := goblin.NewRouter()
r.GET(`/`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "/")
}))
r.GET(`/foo`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "/foo")
}))
r.GET(`/foo/bar`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "/foo/bar")
}))
r.GET(`/foo/bar/:id`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := goblin.GetParam(r.Context(), "id")
fmt.Fprintf(w, "/foo/bar/%v", id)
}))
r.GET(`/foo/bar/:id/:name`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := goblin.GetParam(r.Context(), "id")
name := goblin.GetParam(r.Context(), "name")
fmt.Fprintf(w, "/foo/bar/%v/%v", id, name)
}))
r.GET(`/foo/:id[^\d+$]`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := goblin.GetParam(r.Context(), "id")
fmt.Fprintf(w, "/foo/%v", id)
}))
r.GET(`/foo/:id[^\d+$]/:name`, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := goblin.GetParam(r.Context(), "id")
name := goblin.GetParam(r.Context(), "name")
fmt.Fprintf(w, "/foo/%v/%v", id, name)
}))
http.ListenAndServe(":9999", r)
}
If you want to try it, you can use an _examples.
go version: 1.14
go test -bench=.
Run a total of 203 routes of GithubAPI.
Tested routes:
Memory Consumption:
goblin: 62896 Bytes
beego-mux: 107328 Bytes
HttpRouter: 37096 Bytes
httptreemux: 78896 Bytes
gin: 59128 Bytes
chi: 71528 Bytes
Benchmark Results:
BenchmarkGoblin-4 1363 793539 ns/op 1056676 B/op 3455 allocs/op
BenchmarkBeegoMux-4 1420 972325 ns/op 1142023 B/op 3475 allocs/op
BenchmarkHttpRouter-4 1393 878506 ns/op 1021039 B/op 2604 allocs/op
BenchmarkHttpTreeMux-4 1459 832753 ns/op 1073111 B/op 3108 allocs/op
BenchmarkGin-4 1033 974177 ns/op 1014084 B/op 2642 allocs/op
BenchmarkChi-4 1239 846166 ns/op 1095217 B/op 3047 allocs/op
BenchmarkGoblinRequests-4 60 19327539 ns/op 884059 B/op 11221 allocs/op
BenchmarkBeegoMuxRequests-4 58 19789097 ns/op 969311 B/op 11241 allocs/op
BenchmarkHttpRouterRequests-4 58 21749265 ns/op 848012 B/op 10370 allocs/op
BenchmarkHttpTreeMuxRequests-4 57 24634215 ns/op 900326 B/op 10874 allocs/op
BenchmarkHttpGinRequests-4 45 24686299 ns/op 840777 B/op 10405 allocs/op
BenchmarkHttpChiRequests-4 45 22363389 ns/op 921963 B/op 10811 allocs/op
Router accepts requests and dispatches handlers.
goblin based on trie tree structure.
Please take a look at our CONTRIBUTING.md file.
This project is licensed under the terms of the MIT license.
bmf - A Web Developer in Japan.