gorouter

package module
v4.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2020 License: MIT Imports: 8 Imported by: 6

README

🍃 gorouter

Build Status Go Report Card codecov FOSSA Status license

logo

Go Server/API micro framework, HTTP request router, multiplexer, mux.

📖 ABOUT

Contributors:

Want to contribute ? Feel free to send pull requests!

Have problems, bugs, feature ideas? We are using the github issue tracker to manage them.

📚 Documentation

For documentation (including examples), visit rafallorenz.com/gorouter

For GoDoc reference, visit pkg.go.dev

🚅 Benchmark

➜  gorouter git:(master) ✗ go test -bench=. -cpu=4 -benchmem
test
goos: darwin
goarch: amd64
pkg: github.com/vardius/gorouter/v4
BenchmarkNetHTTP-4              	65005786	        17.9 ns/op	       0 B/op	       0 allocs/op
BenchmarkFastHTTP-4             	69810878	        16.5 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/vardius/gorouter/v4	3.808s

👉 Click here to see all benchmark results.

Features

  • Routing System
  • Middleware System
  • Authentication
  • Fast HTTP
  • Serving Files
  • Multidomain
  • HTTP2 Support
  • Low memory usage
  • Documentation

🚏 HOW TO USE

🖥️ API example setup

📜 License

This package is released under the MIT license. See the complete license in the package:

FOSSA Status

Documentation

Overview

Package gorouter provide request router with middleware

Router

The router determines how to handle http request. GoRouter uses a routing tree. Once one branch of the tree matches, only routes inside that branch are considered, not any routes after that branch. When instantiating router, the root node of tree is created.

Route types

- Static `/hello` (will match requests matching given route)

- Named `/{name}` (will match requests matching given route scheme)

- Regexp `/{name:[a-z]+}` (will match requests matching given route scheme and its regexp)

Wildcards

The values of *named parameter* or *regexp parameters* are accessible via *request context* `params, ok := context.Parameters(req.Context())`. You can get the value of a parameter either by its index in the slice, or by using the `params.Value(name)` method: `:name` or `/{name:[a-z]+}` can be retrieved by `params.Value("name")`.

Defining Routes

A full route definition contain up to three parts:

1. HTTP method under which route will be available

2. The URL path route. This is matched against the URL passed to the router, and can contain named wildcard placeholders *(e.g. {placeholder})* to match dynamic parts in the URL.

3. `http.HandlerFunc`, which tells the router to handle matched requests to the router with handler.

Take the following example:

import "github.com/vardius/gorouter/v4/context"

router.GET("/hello/{name:r([a-z]+)go}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  params, _ := context.Parameters(r.Context())
  fmt.Fprintf(w, "hello, %s!\n", params.Value("name"))
}))

In this case, the route is matched by `/hello/rxxxxxgo` for example, because the `:name` wildcard matches the regular expression wildcard given (`r([a-z]+)go`). However, `/hello/foo` does not match, because "foo" fails the *name* wildcard. When using wildcards, these are returned in the map from request context. The part of the path that the wildcard matched (e.g. *rxxxxxgo*) is used as value.

Example
index := func(_ http.ResponseWriter, _ *http.Request) {
	fmt.Printf("Hello\n")
}

hello := func(_ http.ResponseWriter, r *http.Request) {
	params, _ := context.Parameters(r.Context())
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

router := gorouter.New()
router.GET("/", http.HandlerFunc(index))
router.GET("/hello/{name}", http.HandlerFunc(hello))

// for this example we will mock request
handleNetHTTPRequest("GET", "/", router)
handleNetHTTPRequest("GET", "/hello/guest", router)
Output:

Hello
Hello, guest!
Example (Second)
hello := func(ctx *fasthttp.RequestCtx) {
	params := ctx.UserValue("params").(context.Params)
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

router := gorouter.NewFastHTTPRouter()
router.GET("/hello/{name}", hello)

// for this example we will mock request
handleFastHTTPRequest("GET", "/hello/guest", router.HandleFastHTTP)
Output:

Hello, guest!

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FastHTTPMiddlewareFunc added in v4.1.0

type FastHTTPMiddlewareFunc func(fasthttp.RequestHandler) fasthttp.RequestHandler

FastHTTPMiddlewareFunc is a fasthttp middleware function type

Example
// Global middleware example
// applies to all routes
hello := func(ctx *fasthttp.RequestCtx) {
	params := ctx.UserValue("params").(context.Params)
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

logger := func(next fasthttp.RequestHandler) fasthttp.RequestHandler {
	fn := func(ctx *fasthttp.RequestCtx) {
		fmt.Printf("[%s] %q\n", ctx.Method(), ctx.Path())
		next(ctx)
	}

	return fn
}

router := gorouter.NewFastHTTPRouter(logger)
router.GET("/hello/{name}", hello)

// for this example we will mock request
handleFastHTTPRequest("GET", "/hello/guest", router.HandleFastHTTP)
Output:

[GET] "/hello/guest"
Hello, guest!
Example (Second)
// Route level middleware example
// applies to route and its lower tree
hello := func(ctx *fasthttp.RequestCtx) {
	params := ctx.UserValue("params").(context.Params)
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

logger := func(next fasthttp.RequestHandler) fasthttp.RequestHandler {
	fn := func(ctx *fasthttp.RequestCtx) {
		fmt.Printf("[%s] %q\n", ctx.Method(), ctx.Path())
		next(ctx)
	}

	return fn
}

router := gorouter.NewFastHTTPRouter()
router.GET("/hello/{name}", hello)

// apply middleware to route and all its children
// can pass as many as you want
router.USE("GET", "/hello/{name}", logger)

// for this example we will mock request
handleFastHTTPRequest("GET", "/hello/guest", router.HandleFastHTTP)
Output:

[GET] "/hello/guest"
Hello, guest!
Example (Third)
// Http method middleware example
// applies to all routes under this method
hello := func(ctx *fasthttp.RequestCtx) {
	params := ctx.UserValue("params").(context.Params)
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

logger := func(next fasthttp.RequestHandler) fasthttp.RequestHandler {
	fn := func(ctx *fasthttp.RequestCtx) {
		fmt.Printf("[%s] %q\n", ctx.Method(), ctx.Path())
		next(ctx)
	}

	return fn
}

router := gorouter.NewFastHTTPRouter()
router.GET("/hello/{name}", hello)

// apply middleware to all routes with GET method
// can pass as many as you want
router.USE("GET", "", logger)

// for this example we will mock request
handleFastHTTPRequest("GET", "/hello/guest", router.HandleFastHTTP)
Output:

[GET] "/hello/guest"
Hello, guest!

type FastHTTPRouter added in v4.1.0

type FastHTTPRouter interface {
	// PrettyPrint prints the tree text representation to console
	PrettyPrint() string

	// POST adds fasthttp.RequestHandler as router handler
	// under POST method and given patter
	POST(pattern string, handler fasthttp.RequestHandler)

	// GET adds fasthttp.RequestHandler as router handler
	// under GET method and given patter
	GET(pattern string, handler fasthttp.RequestHandler)

	// PUT adds fasthttp.RequestHandler as router handler
	// under PUT method and given patter
	PUT(pattern string, handler fasthttp.RequestHandler)

	// DELETE adds fasthttp.RequestHandler as router handler
	// under DELETE method and given patter
	DELETE(pattern string, handler fasthttp.RequestHandler)

	// PATCH adds fasthttp.RequestHandler as router handler
	// under PATCH method and given patter
	PATCH(pattern string, handler fasthttp.RequestHandler)

	// OPTIONS adds fasthttp.RequestHandler as router handler
	// under OPTIONS method and given patter
	OPTIONS(pattern string, handler fasthttp.RequestHandler)

	// HEAD adds fasthttp.RequestHandler as router handler
	// under HEAD method and given patter
	HEAD(pattern string, handler fasthttp.RequestHandler)

	// CONNECT adds fasthttp.RequestHandler as router handler
	// under CONNECT method and given patter
	CONNECT(pattern string, handler fasthttp.RequestHandler)

	// TRACE adds fasthttp.RequestHandler as router handler
	// under TRACE method and given patter
	TRACE(pattern string, handler fasthttp.RequestHandler)

	// USE adds middleware functions ([]MiddlewareFunc)
	// to whole router branch under given method and patter
	USE(method, pattern string, fs ...FastHTTPMiddlewareFunc)

	// Handle adds fasthttp.RequestHandler as router handler
	// under given method and patter
	Handle(method, pattern string, handler fasthttp.RequestHandler)

	// Mount another handler as a subrouter
	Mount(pattern string, handler fasthttp.RequestHandler)

	// Compile optimizes Tree nodes reducing static nodes depth when possible
	Compile()

	// HandleFastHTTP dispatches the request to the route handler
	// whose pattern matches the request URL
	HandleFastHTTP(ctx *fasthttp.RequestCtx)

	// ServeFile replies to the request with the
	// contents of the named file or directory.
	ServeFiles(root string, stripSlashes int)

	// NotFound replies to the request with the
	// 404 Error code
	NotFound(fasthttp.RequestHandler)

	// NotFound replies to the request with the
	// 405 Error code
	NotAllowed(fasthttp.RequestHandler)
}

FastHTTPRouter is a fasthttp micro framework, HTTP request router, multiplexer, mux

Example (Mount)
hello := func(ctx *fasthttp.RequestCtx) {
	params := ctx.UserValue("params").(context.Params)
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

subrouter := gorouter.NewFastHTTPRouter()
subrouter.GET("/{name}", hello)

router := gorouter.NewFastHTTPRouter()
router.Mount("/hello", subrouter.HandleFastHTTP)

// for this example we will mock request
handleFastHTTPRequest("GET", "/hello/guest", router.HandleFastHTTP)
Output:

Hello, guest!

func NewFastHTTPRouter added in v4.1.0

func NewFastHTTPRouter(fs ...FastHTTPMiddlewareFunc) FastHTTPRouter

NewFastHTTPRouter creates new Router instance, returns pointer

type MiddlewareFunc

type MiddlewareFunc func(http.Handler) http.Handler

MiddlewareFunc is a http middleware function type

Example
// Global middleware example
// applies to all routes
hello := func(w http.ResponseWriter, r *http.Request) {
	params, _ := context.Parameters(r.Context())
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

logger := func(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		fmt.Printf("[%s] %q\n", r.Method, r.URL.String())
		next.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}

// apply middleware to all routes
// can pass as many as you want
router := gorouter.New(logger)
router.GET("/hello/{name}", http.HandlerFunc(hello))

// for this example we will mock request
handleNetHTTPRequest("GET", "/hello/guest", router)
Output:

[GET] "/hello/guest"
Hello, guest!
Example (Second)
// Route level middleware example
// applies to route and its lower tree
hello := func(w http.ResponseWriter, r *http.Request) {
	params, _ := context.Parameters(r.Context())
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

logger := func(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		fmt.Printf("[%s] %q\n", r.Method, r.URL.String())
		next.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}

router := gorouter.New()
router.GET("/hello/{name}", http.HandlerFunc(hello))

// apply middleware to route and all its children
// can pass as many as you want
router.USE("GET", "/hello/{name}", logger)

// for this example we will mock request
handleNetHTTPRequest("GET", "/hello/guest", router)
Output:

[GET] "/hello/guest"
Hello, guest!
Example (Third)
// Http method middleware example
// applies to all routes under this method
hello := func(w http.ResponseWriter, r *http.Request) {
	params, _ := context.Parameters(r.Context())
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

logger := func(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		fmt.Printf("[%s] %q\n", r.Method, r.URL.String())
		next.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}

router := gorouter.New()
router.GET("/hello/{name}", http.HandlerFunc(hello))

// apply middleware to all routes with GET method
// can pass as many as you want
router.USE("GET", "", logger)

// for this example we will mock request
handleNetHTTPRequest("GET", "/hello/guest", router)
Output:

[GET] "/hello/guest"
Hello, guest!

type Router

type Router interface {
	// PrettyPrint prints the tree text representation to console
	PrettyPrint() string

	// POST adds http.Handler as router handler
	// under POST method and given patter
	POST(pattern string, handler http.Handler)

	// GET adds http.Handler as router handler
	// under GET method and given patter
	GET(pattern string, handler http.Handler)

	// PUT adds http.Handler as router handler
	// under PUT method and given patter
	PUT(pattern string, handler http.Handler)

	// DELETE adds http.Handler as router handler
	// under DELETE method and given patter
	DELETE(pattern string, handler http.Handler)

	// PATCH adds http.Handler as router handler
	// under PATCH method and given patter
	PATCH(pattern string, handler http.Handler)

	// OPTIONS adds http.Handler as router handler
	// under OPTIONS method and given patter
	OPTIONS(pattern string, handler http.Handler)

	// HEAD adds http.Handler as router handler
	// under HEAD method and given patter
	HEAD(pattern string, handler http.Handler)

	// CONNECT adds http.Handler as router handler
	// under CONNECT method and given patter
	CONNECT(pattern string, handler http.Handler)

	// TRACE adds http.Handler as router handler
	// under TRACE method and given patter
	TRACE(pattern string, handler http.Handler)

	// USE adds middleware functions ([]MiddlewareFunc)
	// to whole router branch under given method and patter
	USE(method, pattern string, fs ...MiddlewareFunc)

	// Handle adds http.Handler as router handler
	// under given method and patter
	Handle(method, pattern string, handler http.Handler)

	// Mount another handler as a subrouter
	Mount(pattern string, handler http.Handler)

	// Compile optimizes Tree nodes reducing static nodes depth when possible
	Compile()

	// ServeHTTP dispatches the request to the route handler
	// whose pattern matches the request URL
	ServeHTTP(http.ResponseWriter, *http.Request)

	// ServeFile replies to the request with the
	// contents of the named file or directory.
	ServeFiles(fs http.FileSystem, root string, strip bool)

	// NotFound replies to the request with the
	// 404 Error code
	NotFound(http.Handler)

	// NotFound replies to the request with the
	// 405 Error code
	NotAllowed(http.Handler)
}

Router is a micro framework, HTTP request router, multiplexer, mux

Example (Compile)
health := func(_ http.ResponseWriter, _ *http.Request) {
	fmt.Printf("Health OK!\n")
}

readiness := func(_ http.ResponseWriter, r *http.Request) {
	fmt.Printf("Ready!\n")
}

router := gorouter.New()
router.GET("/v1/health", http.HandlerFunc(health))
router.GET("/v1/readiness", http.HandlerFunc(readiness))

// fmt.Printf("before: %s\n", router.PrettyPrint())

router.Compile()

// fmt.Printf("after: %s\n", router.PrettyPrint())

// for this example we will mock request
handleNetHTTPRequest("GET", "/v1/health", router)
Output:

Health OK!
Example (Mount)
hello := func(w http.ResponseWriter, r *http.Request) {
	params, _ := context.Parameters(r.Context())
	fmt.Printf("Hello, %s!\n", params.Value("name"))
}

// gorouter as subrouter
subrouter := gorouter.New()
subrouter.GET("/{name}", http.HandlerFunc(hello))

// default mux as subrouter
// you can use everything that implements http.Handler interface
unknownSubrouter := http.NewServeMux()
unknownSubrouter.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
	fmt.Println("Hi, guest!")
})

router := gorouter.New()
router.Mount("/hello", subrouter)
router.Mount("/hi", unknownSubrouter)

// for this example we will mock request
handleNetHTTPRequest("GET", "/hello/guest", router)
handleNetHTTPRequest("GET", "/hi", router)
Output:

Hello, guest!
Hi, guest!

func New

func New(fs ...MiddlewareFunc) Router

New creates new net/http Router instance, returns pointer

Directories

Path Synopsis
Package context provide router context
Package context provide router context
Package middleware provide router middleware
Package middleware provide router middleware
Package mux provide route tree
Package mux provide route tree
Package path provide path utils
Package path provide path utils

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL