| @ -1,7 +1,204 @@ | |||
| mux | |||
| === | |||
| [](https://godoc.org/github.com/gorilla/securecookie) | |||
| [](https://travis-ci.org/gorilla/mux) | |||
| gorilla/mux is a powerful URL router and dispatcher. | |||
| Package gorilla/mux implements a request router and dispatcher. | |||
| Read the full documentation here: http://www.gorillatoolkit.org/pkg/mux | |||
| The name mux stands for "HTTP request multiplexer". Like the standard | |||
| http.ServeMux, mux.Router matches incoming requests against a list of | |||
| registered routes and calls a handler for the route that matches the URL | |||
| or other conditions. The main features are: | |||
| * Requests can be matched based on URL host, path, path prefix, schemes, | |||
| header and query values, HTTP methods or using custom matchers. | |||
| * URL hosts and paths can have variables with an optional regular | |||
| expression. | |||
| * Registered URLs can be built, or "reversed", which helps maintaining | |||
| references to resources. | |||
| * Routes can be used as subrouters: nested routes are only tested if the | |||
| parent route matches. This is useful to define groups of routes that | |||
| share common conditions like a host, a path prefix or other repeated | |||
| attributes. As a bonus, this optimizes request matching. | |||
| * It implements the http.Handler interface so it is compatible with the | |||
| standard http.ServeMux. | |||
| Let's start registering a couple of URL paths and handlers: | |||
| func main() { | |||
| r := mux.NewRouter() | |||
| r.HandleFunc("/", HomeHandler) | |||
| r.HandleFunc("/products", ProductsHandler) | |||
| r.HandleFunc("/articles", ArticlesHandler) | |||
| http.Handle("/", r) | |||
| } | |||
| Here we register three routes mapping URL paths to handlers. This is | |||
| equivalent to how http.HandleFunc() works: if an incoming request URL matches | |||
| one of the paths, the corresponding handler is called passing | |||
| (http.ResponseWriter, *http.Request) as parameters. | |||
| Paths can have variables. They are defined using the format {name} or | |||
| {name:pattern}. If a regular expression pattern is not defined, the matched | |||
| variable will be anything until the next slash. For example: | |||
| r := mux.NewRouter() | |||
| r.HandleFunc("/products/{key}", ProductHandler) | |||
| r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) | |||
| r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) | |||
| The names are used to create a map of route variables which can be retrieved | |||
| calling mux.Vars(): | |||
| vars := mux.Vars(request) | |||
| category := vars["category"] | |||
| And this is all you need to know about the basic usage. More advanced options | |||
| are explained below. | |||
| Routes can also be restricted to a domain or subdomain. Just define a host | |||
| pattern to be matched. They can also have variables: | |||
| r := mux.NewRouter() | |||
| // Only matches if domain is "www.domain.com". | |||
| r.Host("www.domain.com") | |||
| // Matches a dynamic subdomain. | |||
| r.Host("{subdomain:[a-z]+}.domain.com") | |||
| There are several other matchers that can be added. To match path prefixes: | |||
| r.PathPrefix("/products/") | |||
| ...or HTTP methods: | |||
| r.Methods("GET", "POST") | |||
| ...or URL schemes: | |||
| r.Schemes("https") | |||
| ...or header values: | |||
| r.Headers("X-Requested-With", "XMLHttpRequest") | |||
| ...or query values: | |||
| r.Queries("key", "value") | |||
| ...or to use a custom matcher function: | |||
| r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { | |||
| return r.ProtoMajor == 0 | |||
| }) | |||
| ...and finally, it is possible to combine several matchers in a single route: | |||
| r.HandleFunc("/products", ProductsHandler). | |||
| Host("www.domain.com"). | |||
| Methods("GET"). | |||
| Schemes("http") | |||
| Setting the same matching conditions again and again can be boring, so we have | |||
| a way to group several routes that share the same requirements. | |||
| We call it "subrouting". | |||
| For example, let's say we have several URLs that should only match when the | |||
| host is "www.domain.com". Create a route for that host and get a "subrouter" | |||
| from it: | |||
| r := mux.NewRouter() | |||
| s := r.Host("www.domain.com").Subrouter() | |||
| Then register routes in the subrouter: | |||
| s.HandleFunc("/products/", ProductsHandler) | |||
| s.HandleFunc("/products/{key}", ProductHandler) | |||
| s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) | |||
| The three URL paths we registered above will only be tested if the domain is | |||
| "www.domain.com", because the subrouter is tested first. This is not | |||
| only convenient, but also optimizes request matching. You can create | |||
| subrouters combining any attribute matchers accepted by a route. | |||
| Subrouters can be used to create domain or path "namespaces": you define | |||
| subrouters in a central place and then parts of the app can register its | |||
| paths relatively to a given subrouter. | |||
| There's one more thing about subroutes. When a subrouter has a path prefix, | |||
| the inner routes use it as base for their paths: | |||
| r := mux.NewRouter() | |||
| s := r.PathPrefix("/products").Subrouter() | |||
| // "/products/" | |||
| s.HandleFunc("/", ProductsHandler) | |||
| // "/products/{key}/" | |||
| s.HandleFunc("/{key}/", ProductHandler) | |||
| // "/products/{key}/details" | |||
| s.HandleFunc("/{key}/details", ProductDetailsHandler) | |||
| Now let's see how to build registered URLs. | |||
| Routes can be named. All routes that define a name can have their URLs built, | |||
| or "reversed". We define a name calling Name() on a route. For example: | |||
| r := mux.NewRouter() | |||
| r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). | |||
| Name("article") | |||
| To build a URL, get the route and call the URL() method, passing a sequence of | |||
| key/value pairs for the route variables. For the previous route, we would do: | |||
| url, err := r.Get("article").URL("category", "technology", "id", "42") | |||
| ...and the result will be a url.URL with the following path: | |||
| "/articles/technology/42" | |||
| This also works for host variables: | |||
| r := mux.NewRouter() | |||
| r.Host("{subdomain}.domain.com"). | |||
| Path("/articles/{category}/{id:[0-9]+}"). | |||
| HandlerFunc(ArticleHandler). | |||
| Name("article") | |||
| // url.String() will be "http://news.domain.com/articles/technology/42" | |||
| url, err := r.Get("article").URL("subdomain", "news", | |||
| "category", "technology", | |||
| "id", "42") | |||
| All variables defined in the route are required, and their values must | |||
| conform to the corresponding patterns. These requirements guarantee that a | |||
| generated URL will always match a registered route -- the only exception is | |||
| for explicitly defined "build-only" routes which never match. | |||
| Regex support also exists for matching Headers within a route. For example, we could do: | |||
| r.HeadersRegexp("Content-Type", "application/(text|json)") | |||
| ...and the route will match both requests with a Content-Type of `application/json` as well as | |||
| `application/text` | |||
| There's also a way to build only the URL host or path for a route: | |||
| use the methods URLHost() or URLPath() instead. For the previous route, | |||
| we would do: | |||
| // "http://news.domain.com/" | |||
| host, err := r.Get("article").URLHost("subdomain", "news") | |||
| // "/articles/technology/42" | |||
| path, err := r.Get("article").URLPath("category", "technology", "id", "42") | |||
| And if you use subrouters, host and path defined separately can be built | |||
| as well: | |||
| r := mux.NewRouter() | |||
| s := r.Host("{subdomain}.domain.com").Subrouter() | |||
| s.Path("/articles/{category}/{id:[0-9]+}"). | |||
| HandlerFunc(ArticleHandler). | |||
| Name("article") | |||
| // "http://news.domain.com/articles/technology/42" | |||
| url, err := r.Get("article").URL("subdomain", "news", | |||
| "category", "technology", | |||
| "id", "42") | |||