CleverGo is a lightweight, feature-rich and trie based high performance HTTP request router.
- Date: 2020/03/13
- CPU: 4 Core
- RAM: 8G
- Go: 1.14
- Detail
Lower is better!
- High Performance: see Benchmark shown above.
- Reverse Route Generation: there are two ways to generate URL by a route: named route and matched route.
- Route Group: as known as subrouter, see route group.
- Friendly to APIs: it is easy to design RESTful APIs and versioning your APIs by route group.
- Middleware: allow to plug middleware in route group or particular route, supports global middleware as well, see middleware exmaple.
- Error Handler allow to custom error response, for example, display an error page.
GO111MODULE=on go get github.com/clevergo/clevergo
or install particular releases:
GO111MODULE=on go get github.com/clevergo/clevergo@version
Replace
version
to particular version.
package main
import (
"fmt"
"net/http"
"github.com/clevergo/clevergo"
)
func home(ctx *clevergo.Context) error {
ctx.WriteString("hello world")
return nil
}
func hello(ctx *clevergo.Context) error {
ctx.WriteString(fmt.Sprintf("hello %s", ctx.Params.String("name")))
return nil
}
func main() {
router := clevergo.NewRouter()
router.Get("/", home)
router.Get("/hello/:name", hello)
http.ListenAndServe(":8080", router)
}
There are some useful functions to retrieve the parameter value.
func (ctx *clevergo.Context) error {
name := ctx.Params.String("name")
page, err := ctx.Params.Int("page")
num, err := ctx.Params.Int64("num")
amount, err := ctx.Params.Uint64("amount")
enable, err := ctx.Params.Bool("enable")
price, err := ctx.Params.Float64("price")
return err
}
Router.UseRawPath
allows to match parameter that contains escaped slash %2f
:
router.UseRawPath = true
router.ServeFiles("/static/*filepath", http.Dir("/path/to/static"))
// sometimes, it is useful to treat http.FileServer as NotFoundHandler,
// such as "/favicon.ico".
router.NotFound = http.FileServer(http.Dir("public"))
queryPost := func (ctx *clevergo.Context) error {
// generates URL by matched route.
url, _ := ctx.Route.URL("year", "2020", "month", "02", "slug", "hello world")
return nil
}
router.Get("/posts/:year/:month/:slug", queryPost, router.RouteName("post"))
// generates URL by named route.
url, _ := router.URL("post", "year", "2020", "month", "02", "slug", "hello world")
Error handler allow to custom error response.
type MyErrorHandler struct {
Tmpl *template.Template
}
func (meh MyErrorHandler) Handle(ctx *clevergo.Context, err error) {
// display an error page.
if err := meh.Tmpl.Execute(ctx.Response, err); err != nil {
ctx.Error(err.Error(), http.StatusInternalServerError)
}
}
router.ErrorHandler = MyErrorHandler{
Tmpl: template.Must(template.New("error").Parse(`<html><body><h1>{{ .Error }}</h1></body></html>`)),
}
Middleware is a Handle
.
authenticator := func(ctx *clevergo.Context) error {
// authenticate returns an user instance and a boolean value indicates whether the provided credential is valid.
if user, ok := authenticate(ctx); !ok {
// returns an error if failed, in order to stop subsequent middlewares and handle.
return clevergo.StatusError{http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized)}
}
// share data between middlewares and handle.
ctx.WithValue("user", user)
return nil
}
auth := func(ctx *clevergo.Context) error {
ctx.WriteString(fmt.Sprintf("hello %v", ctx.Value("user")))
return nil
}
router.Get("/auth", auth, RouteMiddleware(
// middleware for current route.
authenticator,
))
// global middleware, takes gorilla compress middleware as exmaple.
http.ListenAndServe(":8080", handlers.CompressHandler(router))
Middleware also can be used in route group, see Route Group for details.
router := clevergo.NewRouter()
api := router.Group("/api", clevergo.RouteGroupMiddleware(
// middlewares for APIs, such as CORS, authenticator, authorization
))
apiV1 := api.Group("/v1", clevergo.RouteGroupMiddleware(
// middlewares for v1's APIs
))
apiV2 := api.Group("v2", clevergo.RouteGroupMiddleware(
// middlewares for v2's APIs
))
router.Get("/users", queryUsers)
router.Post("/users", createUser)
router.Get("/users/:id", queryUser)
router.Put("/users/:id", updateUser)
router.Delete("/users/:id", deleteUser)
See Route Group for versioning your APIs.
func (ctx *clevergo.Context) error {
// equals to ctx.IsMethod(http.MethodGet).
if ctx.IsGet() {
}
// other shortcuts:
//ctx.IsDelete()
//ctx.IsPatch()
//ctx.IsPost()
//ctx.IsPut()
//ctx.IsOptions()
return nil
}
- Give it a ⭐ and spread the package.
- File an issue for features or bugs.
- Fork and make a pull request.
This project exists thanks to all the people who contribute. [Contribute].
Become a financial contributor and help us sustain our community. [Contribute]
Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]