• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.travis.ymlH A D04-Jul-2017292 2319

LICENSEH A D04-Jul-20171.4 KiB2824

README.mdH A D04-Jul-201711.8 KiB384291

bench_test.goH A D04-Jul-20171.4 KiB5038

context_gorilla.goH A D04-Jul-2017380 2718

context_gorilla_test.goH A D04-Jul-2017868 4125

context_native.goH A D04-Jul-2017380 2517

context_native_test.goH A D04-Jul-2017690 3326

doc.goH A D04-Jul-20178.5 KiB2431

mux.goH A D04-Jul-201715.6 KiB548336

mux_test.goH A D04-Jul-201759.1 KiB1,8741,754

old_test.goH A D04-Jul-201717.1 KiB711581

regexp.goH A D04-Jul-20178.8 KiB327243

route.goH A D04-Jul-201719.7 KiB698402

README.md

1gorilla/mux
2===
3[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux)
4[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux)
5[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge)
6
7![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png)
8
9http://www.gorillatoolkit.org/pkg/mux
10
11Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to
12their respective handler.
13
14The 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:
15
16* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`.
17* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers.
18* URL hosts, paths and query values can have variables with an optional regular expression.
19* Registered URLs can be built, or "reversed", which helps maintaining references to resources.
20* 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.
21
22---
23
24* [Install](#install)
25* [Examples](#examples)
26* [Matching Routes](#matching-routes)
27* [Static Files](#static-files)
28* [Registered URLs](#registered-urls)
29* [Walking Routes](#walking-routes)
30* [Full Example](#full-example)
31
32---
33
34## Install
35
36With a [correctly configured](https://golang.org/doc/install#testing) Go toolchain:
37
38```sh
39go get -u github.com/gorilla/mux
40```
41
42## Examples
43
44Let's start registering a couple of URL paths and handlers:
45
46```go
47func main() {
48	r := mux.NewRouter()
49	r.HandleFunc("/", HomeHandler)
50	r.HandleFunc("/products", ProductsHandler)
51	r.HandleFunc("/articles", ArticlesHandler)
52	http.Handle("/", r)
53}
54```
55
56Here 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.
57
58Paths 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:
59
60```go
61r := mux.NewRouter()
62r.HandleFunc("/products/{key}", ProductHandler)
63r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
64r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
65```
66
67The names are used to create a map of route variables which can be retrieved calling `mux.Vars()`:
68
69```go
70func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) {
71	vars := mux.Vars(r)
72	w.WriteHeader(http.StatusOK)
73	fmt.Fprintf(w, "Category: %v\n", vars["category"])
74}
75```
76
77And this is all you need to know about the basic usage. More advanced options are explained below.
78
79### Matching Routes
80
81Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables:
82
83```go
84r := mux.NewRouter()
85// Only matches if domain is "www.example.com".
86r.Host("www.example.com")
87// Matches a dynamic subdomain.
88r.Host("{subdomain:[a-z]+}.domain.com")
89```
90
91There are several other matchers that can be added. To match path prefixes:
92
93```go
94r.PathPrefix("/products/")
95```
96
97...or HTTP methods:
98
99```go
100r.Methods("GET", "POST")
101```
102
103...or URL schemes:
104
105```go
106r.Schemes("https")
107```
108
109...or header values:
110
111```go
112r.Headers("X-Requested-With", "XMLHttpRequest")
113```
114
115...or query values:
116
117```go
118r.Queries("key", "value")
119```
120
121...or to use a custom matcher function:
122
123```go
124r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
125	return r.ProtoMajor == 0
126})
127```
128
129...and finally, it is possible to combine several matchers in a single route:
130
131```go
132r.HandleFunc("/products", ProductsHandler).
133  Host("www.example.com").
134  Methods("GET").
135  Schemes("http")
136```
137
138Setting 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".
139
140For example, let's say we have several URLs that should only match when the host is `www.example.com`. Create a route for that host and get a "subrouter" from it:
141
142```go
143r := mux.NewRouter()
144s := r.Host("www.example.com").Subrouter()
145```
146
147Then register routes in the subrouter:
148
149```go
150s.HandleFunc("/products/", ProductsHandler)
151s.HandleFunc("/products/{key}", ProductHandler)
152s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
153```
154
155The three URL paths we registered above will only be tested if the domain is `www.example.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.
156
157Subrouters 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.
158
159There's one more thing about subroutes. When a subrouter has a path prefix, the inner routes use it as base for their paths:
160
161```go
162r := mux.NewRouter()
163s := r.PathPrefix("/products").Subrouter()
164// "/products/"
165s.HandleFunc("/", ProductsHandler)
166// "/products/{key}/"
167s.HandleFunc("/{key}/", ProductHandler)
168// "/products/{key}/details"
169s.HandleFunc("/{key}/details", ProductDetailsHandler)
170```
171### Listing Routes
172
173Routes on a mux can be listed using the Router.Walk method—useful for generating documentation:
174
175```go
176package main
177
178import (
179    "fmt"
180    "net/http"
181    "strings"
182
183    "github.com/gorilla/mux"
184)
185
186func handler(w http.ResponseWriter, r *http.Request) {
187    return
188}
189
190func main() {
191    r := mux.NewRouter()
192    r.HandleFunc("/", handler)
193    r.HandleFunc("/products", handler).Methods("POST")
194    r.HandleFunc("/articles", handler).Methods("GET")
195    r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
196    r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
197        t, err := route.GetPathTemplate()
198        if err != nil {
199            return err
200        }
201        // p will contain regular expression is compatible with regular expression in Perl, Python, and other languages.
202        // for instance the regular expression for path '/articles/{id}' will be '^/articles/(?P<v0>[^/]+)$'
203        p, err := route.GetPathRegexp()
204        if err != nil {
205            return err
206        }
207        m, err := route.GetMethods()
208        if err != nil {
209            return err
210        }
211        fmt.Println(strings.Join(m, ","), t, p)
212        return nil
213    })
214    http.Handle("/", r)
215}
216```
217
218### Static Files
219
220Note that the path provided to `PathPrefix()` represents a "wildcard": calling
221`PathPrefix("/static/").Handler(...)` means that the handler will be passed any
222request that matches "/static/*". This makes it easy to serve static files with mux:
223
224```go
225func main() {
226	var dir string
227
228	flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
229	flag.Parse()
230	r := mux.NewRouter()
231
232	// This will serve files under http://localhost:8000/static/<filename>
233	r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))
234
235	srv := &http.Server{
236		Handler:      r,
237		Addr:         "127.0.0.1:8000",
238		// Good practice: enforce timeouts for servers you create!
239		WriteTimeout: 15 * time.Second,
240		ReadTimeout:  15 * time.Second,
241	}
242
243	log.Fatal(srv.ListenAndServe())
244}
245```
246
247### Registered URLs
248
249Now let's see how to build registered URLs.
250
251Routes 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:
252
253```go
254r := mux.NewRouter()
255r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
256  Name("article")
257```
258
259To 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:
260
261```go
262url, err := r.Get("article").URL("category", "technology", "id", "42")
263```
264
265...and the result will be a `url.URL` with the following path:
266
267```
268"/articles/technology/42"
269```
270
271This also works for host and query value variables:
272
273```go
274r := mux.NewRouter()
275r.Host("{subdomain}.domain.com").
276  Path("/articles/{category}/{id:[0-9]+}").
277  Queries("filter", "{filter}")
278  HandlerFunc(ArticleHandler).
279  Name("article")
280
281// url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla"
282url, err := r.Get("article").URL("subdomain", "news",
283                                 "category", "technology",
284                                 "id", "42",
285                                 "filter", "gorilla")
286```
287
288All 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.
289
290Regex support also exists for matching Headers within a route. For example, we could do:
291
292```go
293r.HeadersRegexp("Content-Type", "application/(text|json)")
294```
295
296...and the route will match both requests with a Content-Type of `application/json` as well as `application/text`
297
298There'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:
299
300```go
301// "http://news.domain.com/"
302host, err := r.Get("article").URLHost("subdomain", "news")
303
304// "/articles/technology/42"
305path, err := r.Get("article").URLPath("category", "technology", "id", "42")
306```
307
308And if you use subrouters, host and path defined separately can be built as well:
309
310```go
311r := mux.NewRouter()
312s := r.Host("{subdomain}.domain.com").Subrouter()
313s.Path("/articles/{category}/{id:[0-9]+}").
314  HandlerFunc(ArticleHandler).
315  Name("article")
316
317// "http://news.domain.com/articles/technology/42"
318url, err := r.Get("article").URL("subdomain", "news",
319                                 "category", "technology",
320                                 "id", "42")
321```
322
323### Walking Routes
324
325The `Walk` function on `mux.Router` can be used to visit all of the routes that are registered on a router. For example,
326the following prints all of the registered routes:
327
328```go
329r := mux.NewRouter()
330r.HandleFunc("/", handler)
331r.HandleFunc("/products", handler).Methods("POST")
332r.HandleFunc("/articles", handler).Methods("GET")
333r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
334r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
335    t, err := route.GetPathTemplate()
336    if err != nil {
337        return err
338    }
339    // p will contain a regular expression that is compatible with regular expressions in Perl, Python, and other languages.
340    // For example, the regular expression for path '/articles/{id}' will be '^/articles/(?P<v0>[^/]+)$'.
341    p, err := route.GetPathRegexp()
342    if err != nil {
343        return err
344    }
345    m, err := route.GetMethods()
346    if err != nil {
347        return err
348    }
349    fmt.Println(strings.Join(m, ","), t, p)
350    return nil
351})
352```
353
354## Full Example
355
356Here's a complete, runnable example of a small `mux` based server:
357
358```go
359package main
360
361import (
362	"net/http"
363	"log"
364	"github.com/gorilla/mux"
365)
366
367func YourHandler(w http.ResponseWriter, r *http.Request) {
368	w.Write([]byte("Gorilla!\n"))
369}
370
371func main() {
372	r := mux.NewRouter()
373	// Routes consist of a path and a handler function.
374	r.HandleFunc("/", YourHandler)
375
376	// Bind to a port and pass our router in
377	log.Fatal(http.ListenAndServe(":8000", r))
378}
379```
380
381## License
382
383BSD licensed. See the LICENSE file for details.
384