HttpRouter is a lightweight but very efficient multiplexer. manual:
//julienschmidt/httprouter
/julienschmidt/httprouter
Usage example
package main import ( "fmt" "/julienschmidt/httprouter" "net/http" "log" ) func Index(w , r *, _ ) { (w, "Welcome!\n") } func Hello(w , r *, ps ) { (w, "hello, %s!\n", ("name")) } func main() { router := () ("/", Index) ("/hello/:name", Hello) ((":8080", router)) }
First execute:
go get /julienschmidt/httprouter
Then start the web service:
go run
The usage of ServeMux to the http package is actually very similar. The above defines the handles in two http packages, similar to the types in the http package. The specific correspondence will be explained later. As long as it is considered to be a handler, it is enough to handle the corresponding request. Then, the instance was created using the New() method, and the corresponding handlers were registered for the two modes using the GET() method.
It should be noted that the second pattern "/hello/:name", which can be used for naming matching, similar to the naming capture grouping of regular expressions. The usage will be explained in detail later.
httprouter usage instructions
Variables func CleanPath(p string) string type Handle type Param type Params func ParamsFromContext(ctx ) Params func (ps Params) ByName(name string) string type Router func New() *Router func (r *Router) DELETE(path string, handle Handle) func (r *Router) GET(path string, handle Handle) func (r *Router) HEAD(path string, handle Handle) func (r *Router) Handle(method, path string, handle Handle) func (r *Router) Handler(method, path string, handler ) func (r *Router) HandlerFunc(method, path string, handler ) func (r *Router) Lookup(method, path string) (Handle, Params, bool) func (r *Router) OPTIONS(path string, handle Handle) func (r *Router) PATCH(path string, handle Handle) func (r *Router) POST(path string, handle Handle) func (r *Router) PUT(path string, handle Handle) func (r *Router) ServeFiles(path string, root ) func (r *Router) ServeHTTP(w , req *)
type Handle
The Handle in httprouter is similar, except that it supports the third parameter Params.
type Handle func(, *, Params) Handle is a function that can be registered to a route to handle HTTP requests. Like , but has a third parameter for the values of wildcards (variables).
For example, Index() and Hello() in the previous example are both instances of the Handle type.
func Index(w , r *, _ ) { (w, "Welcome!\n") } func Hello(w , r *, ps ) { (w, "hello, %s!\n", ("name")) }
Register handler
The type is similar to ServeMux in the http package, which implements the interface, so it is a. It can assign requests to registered handlers.
type Router struct {} func (r *Router) ServeHTTP(w , req *)
In addition, Router provides many methods to indicate how to register handlers for paths.
func (r *Router) Handle(method, path string, handle Handle) func (r *Router) Handler(method, path string, handler ) func (r *Router) HandlerFunc(method, path string, handler )
() is used to register a specified Handle for the path, and corresponds to, so it is to directly bind a Handle-type function to the specified path. At the same time, it can also specify http methods: GET, POST, HEAD, PUT, PATCH, DELETE, OPTIONS.
These methods also have corresponding abbreviations:
func (r *Router) DELETE(path string, handle Handle) func (r *Router) GET(path string, handle Handle) func (r *Router) HEAD(path string, handle Handle) func (r *Router) OPTIONS(path string, handle Handle) func (r *Router) PATCH(path string, handle Handle) func (r *Router) POST(path string, handle Handle) func (r *Router) PUT(path string, handle Handle)
For example, Get() is equivalent to ("GET", path, handle).
For example, in the above example, respective functions are registered for both paths.
router := () ("/", Index) ("/hello/:name", Hello)
The Handler() method directly registers for the specified http method and path; the HandlerFunc() method directly registers for the specified http method and path.
Param Related
type Param struct { Key string Value string } Param is a single URL parameter, consisting of a key and a value. type Params []Param Params is a Param-slice, as returned by the router. The slice is ordered, the first URL parameter is also the first slice value. It is therefore safe to read values by the index. func (ps Params) ByName(name string) string ByName returns the value of the first Param which key matches the given name. If no matching Param is found, an empty string is returned.
Param type is a key/value type structure, and the value captured by each group will be saved as this type. As in the previous example:
("/hello/:name", Hello)
Here:name
That is key, when the requested URL path is/hello/abc
, then the value corresponding to the key is abc. That is to say, a Param instance is saved:
Param{ Key: "name", Value: "abc", }
More matching usages are explained later.
Params is Param's slice. That is to say, the key/value captured by each group is stored in this slice.
The ByName(str) method can retrieve the Param's Value that has been saved in the slice based on the Param's Key. As in the example:
func Hello(w , r *, ps ) { (w, "hello, %s!\n", ("name")) } ("/hello/:name", Hello)
hereByName("name")
The search is saved in the slice, Key="name" Param, and returns the Value in this Param.
Since Params is a slice structure, in addition to the ByName() method, you can search key/value, and you can also directly search through the slice method:
ps[0].Key ps[0].Value
Path matching rules
httprouter To register the handler's fit for the path, the path can be named and captured. There are two ways to naming and capture:
Syntax Type :name named parameter *name catch-all parameter
in:name
The capture method is to match the content until the next slash or end of the path. For example, register handler for the following path:
Path: /blog/:category/:post
When the request path is:
/blog/go/request-routers match: category="go", post="request-routers" /blog/go/request-routers/ no match, but the router would redirect /blog/go/ no match /blog/go/request-routers/comments no match
*name
The capture method is to match at the end from the specified location (including the prefix "/"):
Path: /files/*filepath /files/ match: filepath="/" /files/LICENSE match: filepath="/LICENSE" /files/templates/ match: filepath="/templates/" /files no match, but the router would redirect
Let's explain when the redirect will be performed. In the Router type, the first field controls the redirection operation of trailing slashes:
type Router struct { RedirectTrailingSlash bool ... }
If the requested URL path contains or does not contain a trailing slash, but the handler is defined on the registered path containing or does not contain a "/" target, but a 301 redirect will be performed. Simply put, regardless of whether the URL has a trailing slash or not, as long as the registration path does not exist, a handler is defined on the path that removes the trailing slash or adds a trailing slash, and it will automatically redirect.
For example, the registration path is/foo
, the request path is/foo/
, will redirect.
There are several redirects:
Register path:/blog/:category/:post askURLpath:/blog/go/request-routers/ Register path:/blog/:category askURLpath:/blog/go Register path:/files/*filepath askURLpath:/files
Lookup()
func (r *Router) Lookup(method, path string) (Handle, Params, bool)
Lookup retrieves the corresponding Handle and Params based on method+path, and can determine whether the redirect will be performed by the third return value.
More AboutDetailed explanation of how to use Go language HttpRouterPlease check the related links below