trixie

package module
v0.0.0-...-8e2f4c4 Latest Latest
Warning

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

Go to latest
Published: May 5, 2017 License: BSD-2-Clause Imports: 8 Imported by: 0

README

Build Status Go Report Card

What is trixie (Tree multiplexer)?

trixie is a lightweight HTTP request router for Go 1.7+.

The difference between the default mux of Go's net/http package and this mux is, it's supports variables and regex in the routing pattern and matches against the request method. It also based on a tree.

Handler

The handler is a simple standard http.Handler

func(w http.ResponseWriter, r *http.Request) 

Routing Rules

Some examples of valid URL patterns are:

  • /post/all

  • /post/:number

  • /post/:number/page/:number

  • /post/:string

  • /images/#([0-9]{1,})

  • /favicon.ico

  • /:string/:string/:number/:number

  • Parameter elements starting with : indicate a parameter segment in the path.

  • Regex elements starting with # indicate a regex segment in the path.

Routing Priority

The priority rules in the router are simple.

  • A regex segment has the highest priority
  • A parameter Segment has middle priority
  • A static path segment has the lowest priority.

For Instance:

router.GET("/#([0-9]{1,})/post", handler) // highest priority
router.GET("/:string/post", handler) // middle priority
router.GET("/home/post", handler) // lowest priority

Example (Method GET & Regex):

 package main
 
 import (
         "fmt"
         "github.com/donutloop/trixie"
         "net/http"
 )
 
 func main() {
         r := trixie.Classic()
         //URL: http://localhost:8081/user/1
         r.Get("/user/#([0-9]){1,}", userHandler)
         if err := http.ListenAndServe(":81", r); err != nil {
                 fmt.Println(err)
         }
 }
 
 func userHandler(rw http.ResponseWriter, req *http.Request) {
         param := trixie.GetRouteParameters(req) // value of regex segment
         rw.Write([]byte(param["seg1"]))
 }
    

Example (Method GET & String parameter):

 package main
 
 import (
         "fmt"
         "github.com/donutloop/trixie"
         "net/http"
 )
 
 func main() {
         r := trixie.Classic()
         //URL: http://localhost:81/user/1
         r.Get("/user/:string", userHandler)
         if err := http.ListenAndServe(":81", r); err != nil {
                 fmt.Println(err)
         }
 }
 
 func userHandler(rw http.ResponseWriter, req *http.Request) {
         param := trixie.GetRouteParameters(req) // value of parameter segment
         rw.Write([]byte(param["seg1"]))
 }
    

Example (Method GET & Number parameter):

 package main
 
 import (
         "fmt"
         "github.com/donutloop/trixie"
         "net/http"
 )
 
 func main() {
         r := trixie.Classic()
         //URL: http://localhost:81/user/1
         r.Get("/user/:number", userHandler)
         if err := http.ListenAndServe(":81", r); err != nil {
                 fmt.Println(err)
         }
 }
 
 func userHandler(rw http.ResponseWriter, req *http.Request) {
         param := trixie.GetRouteParameters(req) // value of parameter segment
         rw.Write([]byte(param["seg1"]))
 }
    

Example (Added middleware on router):

"easy_middleware" is not part of the router package

package main

import (
        "fmt"
        "github.com/donutloop/easy-middleware"
        "github.com/donutloop/trixie"
        "github.com/donutloop/trixie/middleware"
        "net/http"
)

func main() {
        r := trixie.Classic()

        stack := []middleware.Middleware{
                middleware.Middleware(easy_middleware.NoCache()),
        }

        r.Use(stack...)

        //URL: http://localhost:81/user/1
        r.Get("/home", homeHandler)
        if err := http.ListenAndServe(":81", r); err != nil {
                fmt.Println(err)
        }
}

func homeHandler(rw http.ResponseWriter, req *http.Request) {
        rw.Write([]byte("Hello world!"))
}    

Example (Added middleware on one handler):

"easy_middleware" is not part of the router package

package main

import (
        "fmt"
        "github.com/donutloop/easy-middleware"
        "github.com/donutloop/trixie"
        "github.com/donutloop/trixie/middleware"
        "net/http"
)

func main() {
        r := trixie.Classic()

        stack := middleware.Stack(middleware.Middleware(easy_middleware.NoCache()))
  
        //URL: http://localhost:81/user/1
        r.HandleFunc(http.MethodGet, "/home", stack.ThenFunc(homeHandler))
        if err := http.ListenAndServe(":81", r); err != nil {
                fmt.Println(err)
        }
}

func homeHandler(rw http.ResponseWriter, req *http.Request) {
        rw.Write([]byte("Hello world!"))
}    

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Methods = newMethods()

Functions

func AddCurrentRoute

func AddCurrentRoute(r *http.Request, route RouteInterface) *http.Request

AddCurrentRoute adds a route instance to the current request context

func AddRouteParameters

func AddRouteParameters(r *http.Request, params map[string]string) *http.Request

AddCurrentRoute adds parameters of path to the current request context

func GetQueries

func GetQueries(r *http.Request) *middleware.Queries

GetQueries returns the query variables for the current request.

func GetRouteParameters

func GetRouteParameters(r *http.Request) map[string]string

GetRouteParameter returns the parameters of route for a given request This only works when called inside the handler of the matched route because the matched route is stored in the request context which is cleared after the handler returns

func NewBadMethodError

func NewBadMethodError() error

NewBadMethodError returns an error that formats as the given text.

func NewBadPathError

func NewBadPathError(text string) error

NewBadPathError returns an error that formats as the given text.

func NewMethodValidator

func NewMethodValidator() methodValidator

func NewPathValidator

func NewPathValidator() pathValidator

func NewTree

func NewTree(nodeConstructor func() *Node) func() RouteTreeInterface

NewTree returns an empty Radix Tree

func NodeOfType

func NodeOfType(seg string) nodeType

Types

type BadMethodError

type BadMethodError struct{}

BadMethodError creates error for bad method

func (*BadMethodError) Error

func (bme *BadMethodError) Error() string

type BadPathError

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

BadPathError creates error for bad path

func (*BadPathError) Error

func (bme *BadPathError) Error() string

type Handlers

type Handlers map[string]http.Handler

type Node

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

func NewNode

func NewNode() *Node

NewNode creates a Node instance and setup place for sub nodes

type Route

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

func (*Route) AddHandler

func (r *Route) AddHandler(method string, handler http.Handler) RouteInterface

func (*Route) AddHandlerFunc

func (r *Route) AddHandlerFunc(method string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

func (*Route) AddHandlers

func (r *Route) AddHandlers(handlers Handlers) RouteInterface

func (*Route) GetHandler

func (r *Route) GetHandler(method string) http.Handler

func (*Route) GetHandlers

func (r *Route) GetHandlers() Handlers

func (*Route) GetPattern

func (r *Route) GetPattern() string

func (*Route) HasHandler

func (r *Route) HasHandler(method string) bool

func (*Route) SetPattern

func (r *Route) SetPattern(pattern string) RouteInterface

type RouteInterface

type RouteInterface interface {
	AddHandler(string, http.Handler) RouteInterface
	AddHandlerFunc(string, func(http.ResponseWriter, *http.Request)) RouteInterface
	SetPattern(string) RouteInterface
	GetPattern() string
	GetHandler(string) http.Handler
	HasHandler(string) bool
	GetHandlers() Handlers
	AddHandlers(Handlers) RouteInterface
}

func GetCurrentRoute

func GetCurrentRoute(r *http.Request) RouteInterface

CurrentRoute returns the matched route for the current request. This only works when called inside the handler of the matched route because the matched route is stored in the request context which is cleared after the handler returns

func NewRoute

func NewRoute() RouteInterface

type RouteTreeInterface

type RouteTreeInterface interface {
	UseNode(func() *Node)
	Insert(RouteInterface) RouteInterface
	Find(*Node, string) (RouteInterface, map[string]string, error)
	GetRoot() *Node
}

RouteTreeInterface if like you to implement your own tree version, feel free to do it

type Router

type Router struct {
	// Configurable Handler to be used when no route matches.
	NotFoundHandler http.Handler

	// This defines the flag for new routes.
	StrictSlash bool
	// This defines the flag for new routes.
	SkipClean bool
	// This defines a flag for all routes.
	UseEncodedPath bool
	// This defines a flag for all routes.
	CaseSensitiveURL bool
	// contains filtered or unexported fields
}

Router registers routes to be matched and dispatches a handler.

It implements the http.Handler interface, so it can be registered to serve requests:

var router = trixie.NewRouter()

func main() {
    http.Handle("/", router)
}

This will send all incoming requests to the router.

func Classic

func Classic() *Router

func NewRouter

func NewRouter() *Router

NewRouter returns a new router instance.

func (*Router) Delete

func (r *Router) Delete(pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Delete registers a new delete route for the URL path

func (*Router) Get

func (r *Router) Get(pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Get registers a new get route for the URL path

func (*Router) Handle

func (r *Router) Handle(method string, pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Handle registers a new route with a matcher for the URL path.

func (*Router) HandleFunc

func (r *Router) HandleFunc(method string, pattern string, handler http.Handler) RouteInterface

HandleFunc registers a new route with a matcher for the URL path.

func (*Router) Head

func (r *Router) Head(pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Head registers a new head route for the URL path

func (*Router) Options

func (r *Router) Options(pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Options registers a new options route for the URL path

func (*Router) Patch

func (r *Router) Patch(pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Patch registers a new patch route for the URL path

func (*Router) Path

func (r *Router) Path(pattern string, callback func(route RouteInterface)) RouteInterface

func (*Router) Post

func (r *Router) Post(pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Post registers a new post route for the URL path

func (*Router) Put

func (r *Router) Put(pattern string, handler func(http.ResponseWriter, *http.Request)) RouteInterface

Put registers a new put route for the URL path

func (*Router) RegisterRoute

func (r *Router) RegisterRoute(route RouteInterface)

RegisterRoute registers and validates the given route

func (*Router) ServeHTTP

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

ServeHTTP dispatches the handler registered in the matched route.

When there is a match, the route variables can be retrieved calling trixie.GetRouteParameters(req)

and the route queries can be retrieved calling middleware.GetQueries(req).Get("content-type") or middleware.GetQueries(req).GetAll()

func (*Router) Use

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

Use appends a middleware handler to the mux middleware stack.

func (*Router) UseRoute

func (r *Router) UseRoute(constructor func() RouteInterface)

UseRoute that you can use different route versions See RouteInterface for more details (route.go)

func (*Router) UseTree

func (r *Router) UseTree(constructor func() RouteTreeInterface)

UseTree that you can use different tree versions See TreeInterface for more details (tree.go)

func (*Router) ValidateRoute

func (r *Router) ValidateRoute(route RouteInterface)

type Tree

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

func (*Tree) Find

func (t *Tree) Find(root *Node, path string) (RouteInterface, map[string]string, error)

Find is used to lookup a specific key, returning the value and if it was found

func (*Tree) GetRoot

func (t *Tree) GetRoot() *Node

func (*Tree) Insert

func (t *Tree) Insert(newRoute RouteInterface) RouteInterface

Insert is used to add a new entry or update an existing entry.

func (*Tree) UseNode

func (t *Tree) UseNode(constructer func() *Node)

UseNode that you can use different node versions See NodeInterface for more details (node.go)

type Validator

type Validator interface {
	Validate(RouteInterface) error
}

Validator validates the incomming value against a valid value/s

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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