Giter VIP home page Giter VIP logo

clevergo's Introduction

CleverGo 简体中文

Build Status Financial Contributors on Open Collective Coverage Status Go Report Card GoDoc Release

CleverGo is a lightweight, feature-rich and trie based high performance HTTP request router.

Contents

Benchmark

Benchmark

Features

  • 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.

Installation

GO111MODULE=on go get github.com/clevergo/clevergo

Examples

package main

import (
	"fmt"
	"net/http"

	"github.com/clevergo/clevergo"
)

func home(ctx *clevergo.Context) error {
	return ctx.String(http.StatusOK, "hello world")
}

func hello(ctx *clevergo.Context) error {
	return ctx.HTML(http.StatusOk, fmt.Sprintf("hello %s", ctx.Params.String("name")))
}

func main() {
	router := clevergo.NewRouter()
	router.Get("/", home)
	router.Get("/hello/:name", hello)
	http.ListenAndServe(":8080", router)
}

Response

func text(ctx *clevergo.Context) error {
	return ctx.String(http.StatusOK, "hello world")
}

func html(ctx *clevergo.Context) error {
	return ctx.HTML(http.StatusOK, "<html><body>hello world</body></html>")
}

func json(ctx *clevergo.Context) error {
	return ctx.JSON(http.StatusOK, data)
}

func jsonp(ctx *clevergo.Context) error {
	// equals to ctx.JSONPCallback(http.StatusOK, "callback", data)
	return ctx.JSONP(http.StatusOK, data)
}

func xml(ctx *clevergo.Context) error {
	return ctx.XML(http.StatusOK, data)
}

// Renders a template, you should register renderer first.
// https://github.com/clevergo/jetrenderer
// router.Renderer = jetrenderer.New(jet.NewHTMLSet("./views"))
func render(ctx *clevergo.Context) error {
	return ctx.Render(http.StatusOK, view, data)
}

Params

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

Static Files

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"))

Reverse Route Generation

queryPost := func (ctx *clevergo.Context) error {
	// generates URL by matched route.
	url, _ := ctx.Route.URL("year", "2020", "month", "02", "slug", "hello world")

	// generates URL by naming route.
	// url, _ := ctx.RouteURL("post", "year", "2020", "month", "02", "slug", "hello world")

	return nil
}

router.Get("/posts/:year/:month/:slug", queryPost, router.RouteName("post"))

// generates URL by naming route.
url, _ := router.URL("post", "year", "2020", "month", "02", "slug", "hello world")

Error Handler

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

Middleware is a function func(next Handle) Handle. WrapHH is an adapter that converts func(http.Handler) http.Handler to a middleware.

Built-in middlewares:

Example:

// global middlewares.
serverHeader := func(next clevergo.Handle) clevergo.Handle {
	return func(ctx *clevergo.Context) error {
		// writes server header.
		ctx.Response.Header().Set("Server", "CleverGo")
		return next(ctx)
	}
}
router.Use(
	clevergo.Recovery(true),
	serverHeader,

	// third-party func(http.Handler) http.Handler middlewares
	clevergo.WrapHH(gziphandler.GzipHandler), // https://github.com/nytimes/gziphandler

	// ...
)

authenticator := func(next clevergo.Handle) clevergo.Handle {
	return 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.
			// you can also write response here, and return nil.
			return clevergo.NewError(http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized))
		}

		// share data between middlewares and handle.
		ctx.WithValue("user", user)
		return next(ctx)
	}
}

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,
))

http.ListenAndServe(":8080", router)

Middleware also can be used in route group, see Route Group for details.

Route Group

router := clevergo.NewRouter()

api := router.Group("/api", clevergo.RouteGroupMiddleware(
	// middlewares for APIs, such as CORS, authenticator, authorization
	clevergo.WrapHH(cors.Default().Handler), // https://github.com/rs/cors
))

apiV1 := api.Group("/v1", clevergo.RouteGroupMiddleware(
    // middlewares for v1's APIs
))

apiV2 := api.Group("/v2", clevergo.RouteGroupMiddleware(
    // middlewares for v2's APIs
))

RESTful 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.

Determine Request Method

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()
	//ctx.IsAJAX()
	return nil
}

Contribute

  • Give it a ⭐ and spread the package.
  • File an issue to ask questions, request features or report bugs.
  • Fork and make a pull request.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

Credit

See CREDIT.md.

clevergo's People

Contributors

razonyang avatar beikege avatar monkeywithacupcake avatar whatdoesfoxsaywoo avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.