router

package module
v0.0.0-...-cbb8da7 Latest Latest
Warning

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

Go to latest
Published: Nov 20, 2018 License: MIT Imports: 7 Imported by: 1

README

Router

MIT License Go Doc

Usage

Please see the example directory for a working example.

func main() {
       rm := router.RouteMap{
                "/products": router.MethodHandlers{
                        http.MethodGet:  http.HandlerFunc(ListProducts),
                        http.MethodPost: http.HandlerFunc(AddProduct),
                },
                "/products/:productID": router.MethodHandlers{
                        http.MethodGet:    http.HandlerFunc(GetProduct),
                        http.MethodDelete: http.HandlerFunc(DeleteProduct),
                },
        }

        r := router.NewRouter(rm.VariableMatch())
        http.ListenAndServe(":8000", r)
}
Route Matching

The RouteMap object is essentially just a way to organize http.Handlers in a simple, readable way. This object has helper functions to convert each http.Handler into a HandlerMatcher:

type HandlerMatcher func(r *http.Request) (handler http.Handler, matchFound bool)

This package currently has four built-in HandlerMatchers. Each requires that the request.Method exactly match the specified method in the RouteMap, and each uses different methods to match the request.URL.Path:

  • Glob - returns a match if the request.URL.Path glob matches the pattern used in the RouteMap.
  • Regex - returns a match if the request.URL.Path regex matches the pattern used in the RouteMap.
  • String - returns a match if the request.URL.Path exactly matches the pattern used in the RouteMap.
  • Variable - returns a match if the request.URL.Path variable matches the pattern used in the RouteMap.
Path Variables

Path variables can be fetched using Segments. Segments are just sections in a url's path delimited by the / character.
For example, the segments for /product/p123 are []string{"product", "p123"}.

func GetProduct(w http.ResponseWriter, r *http.Request) {
  productID := router.Segment(r.URL.Path, 1)
  ...
}

There are helper functions for integer segments:

func GetProduct(w http.ResponseWriter, r *http.Request) {
  productID, err := router.IntSegment(r.URL.Path, 1)
  ...
}

Middleware

Middleware adds functionality to a http.Handler:

type Middleware func(http.Handler) http.Handler

This package currently has the following middleware:

Middleware can be applied to a RouteMap:

rm := router.RouteMap{}
rm.ApplyMiddleware(router.LoggingMiddleware(), router.BasicAuthMiddleware("user", "pass"))

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Int64Segment

func Int64Segment(path string, index int) (int64, error)

Int64Segment returns the path's segment at the specified index as an int64.

func IntSegment

func IntSegment(path string, index int) (int, error)

IntSegment returns the path's segment at the specified index as an int.

Example
r := &http.Request{
	URL: &url.URL{Path: "/products/582"},
}

productID, _ := IntSegment(r.URL.Path, 1)
fmt.Println(productID)
Output:

582

func Segment

func Segment(path string, index int) string

Segment returns the path's segment at the specified index.

Example
r := &http.Request{
	URL: &url.URL{Path: "/products/p582"},
}

fmt.Println(Segment(r.URL.Path, 1))
Output:

p582

func Segments

func Segments(path string) []string

Segments returns all segments in path.

Example
r := &http.Request{
	URL: &url.URL{Path: "/products/p582"},
}

fmt.Println(Segments(r.URL.Path))
Output:

[products p582]

Types

type HandlerMatcher

type HandlerMatcher func(r *http.Request) (handler http.Handler, matchFound bool)

A HandlerMatcher is a function that matches a *http.Request to a http.Handler.

func NewGlobHandlerMatcher

func NewGlobHandlerMatcher(method, pattern string, handler http.Handler) HandlerMatcher

NewGlobHandlerMatcher returns a HandlerMatcher that returns a match if and only if the request.Method matches method, and the request.URL.Path glob matches pattern.

Example
matcher := NewGlobHandlerMatcher(http.MethodGet, "/products/*/", nil)
r := &http.Request{
	Method: http.MethodGet,
	URL:    &url.URL{Path: "/products/p582/"},
}

if _, ok := matcher(r); ok {
	fmt.Println("Match successful!")
}
Output:

Match successful!

func NewRegexHandlerMatcher

func NewRegexHandlerMatcher(method, pattern string, handler http.Handler) HandlerMatcher

NewRegexHandlerMatcher returns a HandlerMatcher that returns a match if and only if the request.Method matches method, and the request.URL.Path regex matches pattern.

Example
matcher := NewRegexHandlerMatcher(http.MethodGet, "/products/.+/", nil)
r := &http.Request{
	Method: http.MethodGet,
	URL:    &url.URL{Path: "/products/p582/"},
}

if _, ok := matcher(r); ok {
	fmt.Println("Match successful!")
}
Output:

Match successful!

func NewStringHandlerMatcher

func NewStringHandlerMatcher(method, pattern string, handler http.Handler) HandlerMatcher

NewStringHandlerMatcher returns a HandlerMatcher that returns a match if and only if the request.Method matches method, and the request.URL.Path matches pattern.

Example
matcher := NewStringHandlerMatcher(http.MethodGet, "/home", nil)
r := &http.Request{
	Method: http.MethodGet,
	URL:    &url.URL{Path: "/home"},
}

if _, ok := matcher(r); ok {
	fmt.Println("Match successful!")
}
Output:

Match successful!

func NewVariableHandlerMatcher

func NewVariableHandlerMatcher(method, pattern string, handler http.Handler) HandlerMatcher

NewVariableHandlerMatcher returns a HandlerMatcher that returns a match if and only if the request.Method matches method, and the request.URL.Path variable matches pattern. Path variables are specified in pattern by placing a ':' in front of the variable name. Using a path variable in pattern simply denotes that any value can be used in that path segment. Path variables can be fetched using the Segment helper functions. Note that the following are functionally equivalent:

NewVariableHandlerMatcher(http.MethodGet, "/product/:productID/", handler)
NewGlobHandlerMatcher(http.MethodGet, "/product/*/", handler)
Example
matcher := NewVariableHandlerMatcher(http.MethodGet, "/products/:productID", nil)
r := &http.Request{
	Method: http.MethodGet,
	URL:    &url.URL{Path: "/products/p582"},
}

if _, ok := matcher(r); ok {
	fmt.Println("Match successful!")
}
Output:

Match successful!

type MethodHandlers

type MethodHandlers map[string]http.Handler

MethodHandlers map http methods to http.Handlers.

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware is a function that adds functionality to a handler.

Example
myMiddleware := func(h http.Handler) http.Handler {
	// do some logic here
	return h
}

rm := RouteMap{}
rm.ApplyMiddleware(myMiddleware)
Output:

func BasicAuthMiddleware

func BasicAuthMiddleware(username, password string) Middleware

BasicAuthMiddleware returns a Middleware that requires the specified username password combination to be used in requests' basic auth headers before the original handler is executed. Otherwise, a 401 Status Unauthorized response is returned.

Example
rm := RouteMap{}
rm.ApplyMiddleware(BasicAuthMiddleware("admin", "password"))
Output:

func LoggingMiddleware

func LoggingMiddleware() Middleware

LoggingMiddleware returns a Middleware that logs requests' methods and paths.

Example
rm := RouteMap{}
rm.ApplyMiddleware(LoggingMiddleware())
Output:

type RouteMap

type RouteMap map[string]MethodHandlers

A RouteMap maps url path patterns to MethodHandlers.

func (RouteMap) ApplyMiddleware

func (rm RouteMap) ApplyMiddleware(middleware ...Middleware)

ApplyMiddlware applies each middleware to each http.Handler in rm.

func (RouteMap) GlobMatch

func (rm RouteMap) GlobMatch() []HandlerMatcher

GlobMatch return a HandlerMatcher for each http.Handler in rm using NewGlobHandlerMatcher.

Example
rm := RouteMap{
	"/products": MethodHandlers{
		http.MethodGet:  http.HandlerFunc(nil),
		http.MethodPost: http.HandlerFunc(nil),
	},
	"/products/*/": MethodHandlers{
		http.MethodGet:    http.HandlerFunc(nil),
		http.MethodDelete: http.HandlerFunc(nil),
	},
}

r := NewRouter(rm.GlobMatch())
http.Handle("/", r)
Output:

func (RouteMap) Iterate

func (rm RouteMap) Iterate(fn func(pattern, method string, handler http.Handler))

Iterate calls fn for each handler in rm.

func (RouteMap) RegexMatch

func (rm RouteMap) RegexMatch() []HandlerMatcher

RegexMatch returns a HandlerMatcher for each http.Handler in rm using NewRegexHandlerMatcher.

Example
rm := RouteMap{
	"/products": MethodHandlers{
		http.MethodGet:  http.HandlerFunc(nil),
		http.MethodPost: http.HandlerFunc(nil),
	},
	"/products/.+/": MethodHandlers{
		http.MethodGet:    http.HandlerFunc(nil),
		http.MethodDelete: http.HandlerFunc(nil),
	},
}

r := NewRouter(rm.RegexMatch())
http.Handle("/", r)
Output:

func (RouteMap) StringMatch

func (rm RouteMap) StringMatch() []HandlerMatcher

StringMatch return a HandlerMatcher for each http.Handler in rm using NewStringHandlerMatcher.

Example
rm := RouteMap{
	"/home": MethodHandlers{
		http.MethodGet: http.HandlerFunc(nil),
	},
	"/account": MethodHandlers{
		http.MethodGet:  http.HandlerFunc(nil),
		http.MethodPost: http.HandlerFunc(nil),
		http.MethodPut:  http.HandlerFunc(nil),
	},
}

r := NewRouter(rm.StringMatch())
http.Handle("/", r)
Output:

func (RouteMap) VariableMatch

func (rm RouteMap) VariableMatch() []HandlerMatcher

VariableMatch returns a HandlerMatcher for each http.Handler in rm using NewVariableHandlerMatcher.

Example
rm := RouteMap{
	"/products": MethodHandlers{
		http.MethodGet:  http.HandlerFunc(nil),
		http.MethodPost: http.HandlerFunc(nil),
	},
	"/products/:productID": MethodHandlers{
		http.MethodGet:    http.HandlerFunc(nil),
		http.MethodDelete: http.HandlerFunc(nil),
	},
}

r := NewRouter(rm.VariableMatch())
http.Handle("/", r)
Output:

type Router

type Router struct {
	Matchers []HandlerMatcher
	NotFound func(http.ResponseWriter, *http.Request)
}

Router is the root handler for an application.

Example
rm := RouteMap{}
r := NewRouter(rm.StringMatch())
http.Handle("/", r)
Output:

func NewRouter

func NewRouter(matchers []HandlerMatcher) *Router

NewRouter returns an initialized Router with the specified matchers.

func (*Router) ServeHTTP

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

ServeHTTP attempts to match r to a http.Handler using o.Matchers. If no match is found, o.NotFound is executed.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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