lion

package module
v0.0.0-...-69ee5db Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2019 License: MIT Imports: 15 Imported by: 31

README

Lion Build Status GoDoc License Go Report Card

Lion is a fast HTTP router for building modern scalable modular REST APIs written in Go (golang).

Features

  • Go1-like guarantee: The API will not change in Lion v2.x (once released).
  • Modular: You can define your own modules to easily build a scalable architecture
  • RESTful: You can define modules to groups http resources together.
  • Subdomains: Select which subdomains, hosts a router can match. You can specify it a param or a wildcard e.g. *.example.org. More infos here.
  • Near zero garbage: Lion generates near zero garbage*. The allocations generated comes from the net/http.Request.WithContext() works. It makes a shallow copy of the request.

Table of contents

Install/Update

Lion requires Go 1.7+:

$ go get -u github.com/celrenheit/lion

Next versions of Lion will support the latest Go version and the previous one. For example, when Go 1.8 is out, Lion will support Go 1.7 and Go 1.8.

Hello World

package main

import (
	"fmt"
	"net/http"

	"github.com/celrenheit/lion"
	"context"
)

func Home(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Home")
}

func Hello(w http.ResponseWriter, r *http.Request) {
	name := lion.Param(r, "name")
	fmt.Fprintf(w, "Hello %s!",name)
}

func main() {
	l := lion.Classic()
	l.GetFunc("/", Home)
	l.GetFunc("/hello/:name", Hello)
	l.Run()
}

Try it yourself by running the following command from the current directory:

$ go run examples/hello/hello.go

Getting started with modules and resources

We are going to build a sample products listing REST api (without database handling to keep it simple):


func main() {
	l := lion.Classic()
	api := l.Group("/api")
	api.Module(Products{})
	l.Run()
}

// Products module is accessible at url: /api/products
// It handles getting a list of products or creating a new product
type Products struct{}

func (p Products) Base() string {
	return "/products"
}

func (p Products) Get(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Fetching all products")
}

func (p Products) Post(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Creating a new product")
}

func (p Products) Routes(r *lion.Router) {
	// Defining a resource for getting, editing and deleting a single product
	r.Resource("/:id", OneProduct{})
}

// OneProduct resource is accessible at url: /api/products/:id
// It handles getting, editing and deleting a single product
type OneProduct struct{}

func (p OneProduct) Get(w http.ResponseWriter, r *http.Request) {
	id := lion.Param(r, "id")
	fmt.Fprintf(w, "Getting product: %s", id)
}

func (p OneProduct) Put(w http.ResponseWriter, r *http.Request) {
	id := lion.Param(r, "id")
	fmt.Fprintf(w, "Updating article: %s", id)
}

func (p OneProduct) Delete(w http.ResponseWriter, r *http.Request) {
	id := lion.Param(r, "id")
	fmt.Fprintf(w, "Deleting article: %s", id)
}

Try it yourself. Run:

$ go run examples/modular-hello/modular-hello.go

Open your web browser to http://localhost:3000/api/products or http://localhost:3000/api/products/123. You should see "Fetching all products" or "Getting product: 123".

Using net/http.Handler

Handlers should implement the native net/http.Handler:

l.Get("/get", get)
l.Post("/post", post)
l.Put("/put", put)
l.Delete("/delete", delete)
Using net/http.HandlerFunc

You can use native net/http.Handler (func(w http.ResponseWriter, r *http.Request)):

func myHandlerFunc(w http.ResponseWriter, r *http.Request)  {
  fmt.Fprintf(w, "Hi!")
}

l.GetFunc("/get", myHandlerFunc)
l.PostFunc("/post", myHandlerFunc)
l.PutFunc("/put", myHandlerFunc)
l.DeleteFunc("/delete", myHandlerFunc)

Middlewares

Middlewares should implement the Middleware interface:

type Middleware interface {
	ServeNext(http.Handler) http.Handler
}

The ServeNext function accepts a http.Handler and returns a http.Handler.

You can also use MiddlewareFuncs which are basically just func(http.Handler) http.Handler

For example:

func middlewareFunc(next Handler) Handler  {
	return next
}
Using Named Middlewares

Named middlewares are designed to be able to reuse a previously defined middleware. For example, if you have a EnsureAuthenticated middleware that check whether a user is logged in. You can define it once and reuse later in your application.

l := lion.New()
l.Define("EnsureAuthenticated", NewEnsureAuthenticatedMiddleware())

To reuse it later in your application, you can use the UseNamed method. If it cannot find the named middleware if the current Router instance it will try to find it in the parent router. If a named middleware is not found it will panic.

api := l.Group("/api")
api.UseNamed("EnsureAuthenticated")
Using Third-Party Middlewares
Negroni

In v1, negroni was supported directly using UseNegroni. It still works but you will have to use .UseNext and pass it a negroni.HandlerFunc: func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)

This way if you prefer to use this kind of middleware, you can.

You can use Negroni middlewares you can find a list of third party middlewares here

l := lion.New()
l.UseNext(negroni.NewRecovery().ServeHTTP)
l.Run()

Matching Subdomains/Hosts

You can match a specific or multiple hosts. You can use patterns in the same way they are currently used for routes with only some edge cases. The main difference is that you will have to use the '$' character instead of ':' to define a parameter.

admin.example.com will match admin.example.com $username.blog.com will match messi.blog.com will not match my.awesome.blog.com *.example.com will match my.admin.example.com

l := New()

// Group by /api basepath
api := l.Group("/api")

// Specific to v1
v1 := api.Subrouter().
	Host("v1.example.org")

v1.Get("/", v1Handler)

// Specific to v2
v2 := api.Subrouter().
	Host("v2.example.org")

v2.Get("/", v2Handler)
l.Run()

Resources

You can define a resource to represent a REST, CRUD api resource. You define global middlewares using Uses() method. For defining custom middlewares for each http method, you have to create a function which name is composed of the http method suffixed by "Middlewares". For example, if you want to define middlewares for the Get method you will have to create a method called: GetMiddlewares().

A resource is defined by the following methods. Everything is optional:


// Global middlewares for the resource (Optional)
Uses() Middlewares

// Middlewares for the http methods (Optional)
GetMiddlewares() Middlewares
PostMiddlewares() Middlewares
PutMiddlewares() Middlewares
DeleteMiddlewares() Middlewares


// HandlerFuncs for each HTTP Methods (Optional)
Get(w http.ResponseWriter, r *http.Request)
Post(w http.ResponseWriter, r *http.Request)
Put(w http.ResponseWriter, r *http.Request)
Delete(w http.ResponseWriter, r *http.Request)

Example:

package main

type todolist struct{}

func (t todolist) Uses() lion.Middlewares {
	return lion.Middlewares{lion.NewLogger()}
}

func (t todolist) Get(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "getting todos")
}

func main() {
	l := lion.New()
	l.Resource("/todos", todolist{})
	l.Run()
}

## Modules

Modules are a way to modularize an api which can then define submodules, subresources and custom routes. A module is defined by the following methods:

// Required: Base url pattern of the module
Base() string

// Routes accepts a Router instance. This method is used to define the routes of this module.
// Each routes defined are relative to the Base() url pattern
Routes(*Router)

// Optional: Requires named middlewares. Refer to Named Middlewares section
Requires() []string
package main

type api struct{}

// Required: Base url
func (t api) Base() string { return "/api" }

// Required: Here you can declare sub-resources, submodules and custom routes.
func (t api) Routes(r *lion.Router) {
	r.Module(v1{})
	r.Get("/custom", t.CustomRoute)
}

// Optional: Attach Get method to this Module.
// ====> A Module is also a Resource.
func (t api) Get(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "This also a resource accessible at http://localhost:3000/api")
}

// Optional: Defining custom routes
func (t api) CustomRoute(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "This a custom route for this module http://localhost:3000/api/")
}

func main() {
	l := lion.New()
	// Registering the module
	l.Module(api{})
	l.Run()
}

Examples

Using GET, POST, PUT, DELETE http methods
l := lion.Classic()

// Using Handlers
l.Get("/get", get)
l.Post("/post", post)
l.Put("/put", put)
l.Delete("/delete", delete)

// Using functions
l.GetFunc("/get", getFunc)
l.PostFunc("/post", postFunc)
l.PutFunc("/put", putFunc)
l.DeleteFunc("/delete", deleteFunc)

l.Run()
Using middlewares
func main() {
	l := lion.Classic()

	// Using middleware
	l.Use(lion.NewLogger())

	// Using middleware functions
	l.UseFunc(someMiddlewareFunc)

	l.GetFunc("/hello/:name", Hello)

	l.Run()
}
Group routes by a base path
l := lion.Classic()
api := l.Group("/api")

v1 := l.Group("/v1")
v1.GetFunc("/somepath", gettingFromV1)

v2 := l.Group("/v2")
v2.GetFunc("/somepath", gettingFromV2)

l.Run()
Mounting a router into a base path
l := lion.Classic()

sub := lion.New()
sub.GetFunc("/somepath", getting)


l.Mount("/api", sub)
Default middlewares

lion.Classic() creates a router with default middlewares (Recovery, RealIP, Logger, Static). If you wish to create a blank router without any middlewares you can use lion.New().

func main()  {
	// This a no middlewares registered
	l := lion.New()
	l.Use(lion.NewLogger())

	l.GetFunc("/hello/:name", Hello)

	l.Run()
}
Custom Middlewares

Custom middlewares should implement the Middleware interface:

type Middleware interface {
	ServeNext(Handler) Handler
}

You can also make MiddlewareFuncs to use using .UseFunc() method. It has to accept a Handler and return a Handler:

func(next Handler) Handler
Custom Logger example
type logger struct{}

func (*logger) ServeNext(next lion.Handler) lion.Handler {
	return lion.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()

		next.ServeHTTPC(c, w, r)

		fmt.Printf("Served %s in %s\n", r.URL.Path, time.Since(start))
	})
}

Then in the main function you can use the middleware using:

l := lion.New()

l.Use(&logger{})
l.GetFunc("/hello/:name", Hello)
l.Run()

Benchmarks

TODO: Update this when v2 is released.

Contributing

Want to contribute to Lion ? Awesome! Feel free to submit an issue or a pull request.

Here are some ways you can help:

  • Report bugs
  • Share a middleware or a module
  • Improve code/documentation
  • Propose new features
  • and more...

License

The project is licensed under the MIT license available here: https://github.com/celrenheit/lion/blob/master/LICENSE.

The benchmarks present in bench_test.go is licensed under a BSD-style license available here: https://github.com/julienschmidt/go-http-routing-benchmark/blob/master/LICENSE.

Todo

  • Support for Go 1.7 context
  • Host matching
  • Automatic OPTIONS handler
  • Modules
    • JWT Auth module
  • Better static file handling
  • More documentation

Credits

Lion v1 was inspired by pressly/chi. If Lion is not the right http router for you, check out chi.

Parts of Lion taken for other projects:

  • Negroni
    • Static and Recovery middlewares are taken from Negroni
  • Goji
    • RealIP middleware is taken from goji
  • Gin
    • ResponseWriter and Logger inspiration are inspired by gin

Documentation

Overview

Package lion is a fast HTTP router for building modern scalable modular REST APIs in Go.

Install and update:

go get -u github.com/celrenheit/lion

Getting started:

Start by importing "github.com/celrenheit/lion" into your project. Then you need to create a new instance of the router using lion.New() for a blank router or lion.Classic() for a router with default middlewares included.

Here is a simple hello world example:

package main

import (
	"fmt"
	"net/http"

	"github.com/celrenheit/lion"
	"context"
)

func Home(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Home")
}

func Hello(w http.ResponseWriter, r *http.Request) {
	name := lion.Param(c, "name")
	fmt.Fprintf(w, "Hello "+name)
}

func main() {
	l := lion.Classic()
	l.GetFunc("/", Home)
	l.GetFunc("/hello/:name", Hello)
	l.Run()
}

You can open your web browser to http://localhost:3000/hello/world and you should see "Hello world". If it finds a PORT environnement variable it will use that. Otherwise, it will use run the server at localhost:3000. If you wish to provide a specific port you can run it using: l.Run(":8080")

Index

Constants

View Source
const (
	GET     = "GET"
	HEAD    = "HEAD"
	POST    = "POST"
	PUT     = "PUT"
	DELETE  = "DELETE"
	TRACE   = "TRACE"
	OPTIONS = "OPTIONS"
	CONNECT = "CONNECT"
	PATCH   = "PATCH"
)

HTTP methods constants

Variables

View Source
var (
	// ErrInvalidRedirectStatusCode is used to notify when an invalid redirect status code is used on Context.Redirect()
	ErrInvalidRedirectStatusCode = errors.New("Invalid redirect status code")
)

Functions

func Param

func Param(req *http.Request, key string) string

Param returns the value of a url param base on the passed context

Types

type Context

type Context interface {
	context.Context
	http.ResponseWriter
	Param(key string) string
	ParamOk(key string) (string, bool)
	Clone() Context

	Request() *http.Request

	// Request
	Cookie(name string) (*http.Cookie, error)
	Query(name string) string
	GetHeader(key string) string

	// Response
	WithStatus(code int) Context
	WithHeader(key, value string) Context
	WithCookie(cookie *http.Cookie) Context

	// Rendering
	JSON(data interface{}) error
	XML(data interface{}) error
	String(format string, a ...interface{}) error
	Error(err error) error
	File(path string) error
	Attachment(path, filename string) error
	Redirect(urlStr string) error
}

Context is used to store url params and is a convinient utility to read informations from the current *http.Request and render to the current http.ResponseWriter. It implements the http.ResponseWriter interface.

func C

func C(req *http.Request) Context

C returns a Context based on a context.Context passed. If it does not convert to Context, it creates a new one with the context passed as argument.

type HTTPError

type HTTPError interface {
	error
	Status() int
}

HTTPError allows to write an error to http.ResponseWriter. You can use it with Context. Like in the following example:

func(c lion.Context) {
	c.Error(lion.ErrorUnauthorized)
}

This will return a response with status code 401 and a body of "Unauthorized". Check below for the available http error

var (

	// ErrorBadRequest returns a BadRequest response with the corresponding body
	ErrorBadRequest HTTPError = httpError{http.StatusBadRequest}
	// ErrorUnauthorized returns a Unauthorized response with the corresponding body
	ErrorUnauthorized HTTPError = httpError{http.StatusUnauthorized}
	// ErrorForbidden returns a Forbidden response with the corresponding body
	ErrorForbidden HTTPError = httpError{http.StatusForbidden}
	// ErrorNotFound returns a NotFound response with the corresponding body
	ErrorNotFound HTTPError = httpError{http.StatusNotFound}
	// ErrorMethodNotAllowed returns a MethodNotAllowed response with the corresponding body
	ErrorMethodNotAllowed HTTPError = httpError{http.StatusMethodNotAllowed}

	// ErrorInternalServer returns a InternalServerError response with the corresponding body
	ErrorInternalServer HTTPError = httpError{http.StatusInternalServerError}
)

type Middleware

type Middleware interface {
	ServeNext(http.Handler) http.Handler
}

Middleware interface that takes as input a Handler and returns a Handler

type MiddlewareFunc

type MiddlewareFunc func(http.Handler) http.Handler

MiddlewareFunc wraps a function that takes as input a Handler and returns a Handler. So that it implements the Middlewares interface

func (MiddlewareFunc) ServeNext

func (m MiddlewareFunc) ServeNext(next http.Handler) http.Handler

ServeNext makes MiddlewareFunc implement Middleware

type Middlewares

type Middlewares []Middleware

Middlewares is an array of Middleware

func (Middlewares) BuildHandler

func (middlewares Middlewares) BuildHandler(handler http.Handler) http.Handler

BuildHandler builds a chain of middlewares from a passed Handler and returns a Handler

func (Middlewares) ServeNext

func (middlewares Middlewares) ServeNext(next http.Handler) http.Handler

ServeNext allows Middlewares to implement the Middleware interface. This is useful to allow Grouping middlewares together and being able to use them as a single Middleware.

type Module

type Module interface {
	Resource
	Base() string
	Routes(*Router)
}

Module represent an independent router entity. It should be used to group routes and subroutes together.

type Resource

type Resource interface{}

Resource defines the minimum required methods

type Route

type Route interface {
	// WithName allows to specify a name for the current route
	WithName(name string) Route

	// Methods returns the http methods set for the current route
	Methods() (methods []string)

	// Host returns the host set
	Host() string

	// Name returns the name set for the current route
	Name() string

	// Pattern returns the underlying pattern for the route
	Pattern() string

	// Handler return the according http.Handler for the method specified
	// The returned handler is already built using the middlewares in *Router
	Handler(method string) http.Handler

	// Path returns a path with the provided params.
	// If any of the params is missing this function will return an error.
	Path(params map[string]string) (string, error)

	// Build allows you to build params by params.
	// For example: route.Build().WithParam("id", "123").WithParam("post_id", "456")
	Build() RoutePathBuilder

	// Convenient alias for Build().WithParam()
	// Calling this method will create a new RoutePathBuilder
	WithParam(key, value string) RoutePathBuilder
}

Route defines a single route registered in your Router. A Route corresponds to the pattern and host given. It contains the handlers for each HTTP methods.

type RoutePathBuilder

type RoutePathBuilder interface {
	WithParam(key, value string) RoutePathBuilder
	Path() (string, error)
}

RoutePathBuilder is a convenient utility to build path given each url parameters. Here is a simple example usage.

router := New()
route := router.Get("/posts/:user", postsHandler)
path := route.Build().WithParam("user", "123")
// path should be equal to "/posts/123"

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router is the main component of Lion. It is responsible for registering handlers and middlewares

func New

func New(mws ...Middleware) *Router

New creates a new router instance

func (*Router) ANY

func (r *Router) ANY(pattern string, handler func(Context)) Route

ANY registers the provided contextual Handler for all of the allowed http methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH

func (*Router) Any

func (r *Router) Any(pattern string, handler http.Handler) Route

Any registers the provided Handler for all of the allowed http methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH

func (*Router) AnyFunc

func (r *Router) AnyFunc(pattern string, handler http.HandlerFunc) Route

AnyFunc registers the provided HandlerFunc for all of the allowed http methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH

func (*Router) CONNECT

func (r *Router) CONNECT(pattern string, handler func(Context)) Route

CONNECT registers an http CONNECT method receiver with the provided contextual Handler

func (*Router) Configure

func (r *Router) Configure(opts ...RouterOption)

Configure allows you to customize a Router using RouterOption

func (*Router) Connect

func (r *Router) Connect(pattern string, handler http.Handler) Route

Connect registers an http CONNECT method receiver with the provided Handler

func (*Router) ConnectFunc

func (r *Router) ConnectFunc(pattern string, fn http.HandlerFunc) Route

ConnectFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) DELETE

func (r *Router) DELETE(pattern string, handler func(Context)) Route

DELETE registers an http DELETE method receiver with the provided contextual Handler

func (*Router) Define

func (r *Router) Define(name string, mws ...Middleware)

Define registers some middleware using a name for reuse later using UseNamed method.

func (*Router) DefineFunc

func (r *Router) DefineFunc(name string, mws ...MiddlewareFunc)

DefineFunc is a convenience wrapper for Define() to use MiddlewareFunc instead of a Middleware instance

func (*Router) Delete

func (r *Router) Delete(pattern string, handler http.Handler) Route

Delete registers an http DELETE method receiver with the provided Handler

func (*Router) DeleteFunc

func (r *Router) DeleteFunc(pattern string, fn http.HandlerFunc) Route

DeleteFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) GET

func (r *Router) GET(pattern string, handler func(Context)) Route

GET registers an http GET method receiver with the provided contextual Handler

func (*Router) Get

func (r *Router) Get(pattern string, handler http.Handler) Route

Get registers an http GET method receiver with the provided Handler

func (*Router) GetFunc

func (r *Router) GetFunc(pattern string, fn http.HandlerFunc) Route

GetFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) Group

func (r *Router) Group(pattern string, mws ...Middleware) *Router

Group creates a subrouter with parent pattern provided.

func (*Router) HEAD

func (r *Router) HEAD(pattern string, handler func(Context)) Route

HEAD registers an http HEAD method receiver with the provided contextual Handler

func (*Router) Handle

func (r *Router) Handle(method, pattern string, handler http.Handler) Route

Handle is the underling method responsible for registering a handler for a specific method and pattern.

func (*Router) HandleFunc

func (r *Router) HandleFunc(method, pattern string, fn http.HandlerFunc) Route

HandleFunc wraps a HandlerFunc and pass it to Handle method

func (*Router) Head

func (r *Router) Head(pattern string, handler http.Handler) Route

Head registers an http HEAD method receiver with the provided Handler

func (*Router) HeadFunc

func (r *Router) HeadFunc(pattern string, fn http.HandlerFunc) Route

HeadFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) Host

func (r *Router) Host(hostpattern string) *Router

Host sets the host for the current router instances. You can use patterns in the same way they are currently used for routes but in reverse order (params on the left)

NOTE: You have to use the '$' character instead of ':' for matching host parameters.

The following patterns works:

admin.example.com			will match			admin.example.com
$username.blog.com			will match			messi.blog.com
					will not match			my.awesome.blog.com
*.example.com				will match			my.admin.example.com

The following patterns are not allowed:

mail.*
*

func (*Router) Module

func (r *Router) Module(modules ...Module)

Module register modules for the current router instance.

func (*Router) Mount

func (r *Router) Mount(pattern string, sub *Router, mws ...Middleware)

Mount mounts a subrouter at the provided pattern

func (*Router) OPTIONS

func (r *Router) OPTIONS(pattern string, handler func(Context)) Route

OPTIONS registers an http OPTIONS method receiver with the provided contextual Handler

func (*Router) Options

func (r *Router) Options(pattern string, handler http.Handler) Route

Options registers an http OPTIONS method receiver with the provided Handler

func (*Router) OptionsFunc

func (r *Router) OptionsFunc(pattern string, fn http.HandlerFunc) Route

OptionsFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) PATCH

func (r *Router) PATCH(pattern string, handler func(Context)) Route

PATCH registers an http PATCH method receiver with the provided contextual Handler

func (*Router) POST

func (r *Router) POST(pattern string, handler func(Context)) Route

POST registers an http POST method receiver with the provided contextual Handler

func (*Router) PUT

func (r *Router) PUT(pattern string, handler func(Context)) Route

PUT registers an http PUT method receiver with the provided contextual Handler

func (*Router) Patch

func (r *Router) Patch(pattern string, handler http.Handler) Route

Patch registers an http PATCH method receiver with the provided Handler

func (*Router) PatchFunc

func (r *Router) PatchFunc(pattern string, fn http.HandlerFunc) Route

PatchFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) Post

func (r *Router) Post(pattern string, handler http.Handler) Route

Post registers an http POST method receiver with the provided Handler

func (*Router) PostFunc

func (r *Router) PostFunc(pattern string, fn http.HandlerFunc) Route

PostFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) Put

func (r *Router) Put(pattern string, handler http.Handler) Route

Put registers an http PUT method receiver with the provided Handler

func (*Router) PutFunc

func (r *Router) PutFunc(pattern string, fn http.HandlerFunc) Route

PutFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) Resource

func (r *Router) Resource(pattern string, resource Resource)

Resource registers a Resource with the corresponding pattern

func (*Router) Route

func (r *Router) Route(name string) Route

Route get the Route associated with the name specified. Each Route corresponds to a pattern and a host registered.

GET host1.org/users
POST host1.org/users

share the same Route. If you want to get the http.Handler for a specific HTTP method, please refer to Route.Handler(method) method.

func (*Router) Routes

func (r *Router) Routes() Routes

Routes returns the Routes associated with the current Router instance.

func (*Router) Run

func (r *Router) Run(addr ...string)

Run calls http.ListenAndServe for the current router. If no addresses are specified as arguments, it will use the PORT environnement variable if it is defined. Otherwise, it will listen on port 3000 of the localmachine

r := New()
r.Run() // will call
r.Run(":8080")

func (*Router) RunTLS

func (r *Router) RunTLS(addr, certFile, keyFile string)

RunTLS calls http.ListenAndServeTLS for the current router

r := New()
r.RunTLS(":3443", "cert.pem", "key.pem")

func (*Router) ServeFile

func (r *Router) ServeFile(base, path string)

ServeFile serve a specific file located at the passed path

l := New()
l.ServeFile("/robots.txt", "path/to/robots.txt")

func (*Router) ServeFiles

func (r *Router) ServeFiles(base string, root http.FileSystem)

ServeFiles serves files located in root http.FileSystem

This can be used as shown below:

r := New()
r.ServeFiles("/static", http.Dir("static")) // This will serve files in the directory static with /static prefix

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP finds the handler associated with the request's path. If it is not found it calls the NotFound handler

func (*Router) Subrouter

func (r *Router) Subrouter(mws ...Middleware) *Router

Subrouter creates a new router based on the parent router.

A subrouter has the same pattern and host as the parent router. It has it's own middlewares.

func (*Router) TRACE

func (r *Router) TRACE(pattern string, handler func(Context)) Route

TRACE registers an http TRACE method receiver with the provided contextual Handler

func (*Router) Trace

func (r *Router) Trace(pattern string, handler http.Handler) Route

Trace registers an http TRACE method receiver with the provided Handler

func (*Router) TraceFunc

func (r *Router) TraceFunc(pattern string, fn http.HandlerFunc) Route

TraceFunc wraps a HandlerFunc as a Handler and registers it to the router

func (*Router) USE

func (r *Router) USE(middlewares ...func(func(Context)) func(Context))

USE allows you to use contextual middlewares. Example:

router.USE(func (next func(Context)) func(Context) {
	return func(c Context) {
		if c.GetHeader("Authorization") == "" {
			c.Error(lion.ErrorUnauthorized)
			return
		}
		next(c)
	}
})

This will return an HTTP 401 Unauthorized response if the "Authorization" header is set. Otherwise, it will continue to next middleware.

func (*Router) Use

func (r *Router) Use(middlewares ...Middleware)

Use registers middlewares to be used

func (*Router) UseFunc

func (r *Router) UseFunc(middlewareFuncs ...MiddlewareFunc)

UseFunc wraps a MiddlewareFunc as a Middleware and registers it middlewares to be used

func (*Router) UseNamed

func (r *Router) UseNamed(name string)

UseNamed adds a middleware already defined using Define method. If it cannot find it in the current router, it will look for it in the parent router.

func (*Router) UseNext

func (r *Router) UseNext(funcs ...func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc))

UseNext allows to use middlewares with the following form: func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) Previously named: UseNegroniFunc. This can be useful if you want to use negroni style middleware or a middleware already built by the community.

type RouterOption

type RouterOption func(*Router)

RouterOption configure a Router

func WithLogger

func WithLogger(logger *log.Logger) RouterOption

WithLogger allows to customize the underlying logger

func WithNotFoundHandler

func WithNotFoundHandler(h http.Handler) RouterOption

WithNotFoundHandler override the default not found handler

func WithServer

func WithServer(server *http.Server) RouterOption

WithServer allows to customize the underlying http.Server Note: when using Run() the handler and the address will change

type Routes

type Routes []Route

Routes is an slice of Route. Check Routes.ByName or Routes.ByPattern to find out if it is useful to you

func (Routes) ByName

func (rs Routes) ByName(name string) Route

ByName returns the route corresponding to the name given. It returns nil otherwise.

func (Routes) ByPattern

func (rs Routes) ByPattern(pattern string) Route

ByPattern returns the route corresponding to the pattern given. It returns nil otherwise.

func (Routes) String

func (rs Routes) String() string

String returns a string representation of a list of routes.

Directories

Path Synopsis
examples
internal

Jump to

Keyboard shortcuts

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