mux

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2023 License: Apache-2.0 Imports: 10 Imported by: 0

README

mux

实现了一个请求路由器和调度程序,用于将传入的请求匹配到它们各自的处理程序

安装

go get -u github.com/go-mux/mux

示例

简单使用
func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/products", ProductsHandler)
    r.HandleFunc("/articles", ArticlesHandler)
    http.Handle("/", r)
}
路径参数
r := mux.NewRouter()
r.HandleFunc("/products/{key}", ProductHandler)
r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler)
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
子域
r := mux.NewRouter()
r.Host("www.example.com")
r.Host("{subdomain:[a-z]+}.example.com")
其他
// 前缀匹配
r.PathPrefix("/products/")
// 方法匹配
r.Methods("GET", "POST")
// schemes匹配
r.Schemes("https")
// header匹配
r.Headers("X-Requested-With", "XMLHttpRequest")
// 参数匹配
r.Queries("key", "value")
// 自定义匹配
r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
return r.ProtoMajor == 0
})
链式调用
r.HandleFunc("/products", ProductsHandler).
  Host("www.example.com").
  Methods("GET").
  Schemes("http")
顺序

如果两条路线匹配,则第一条路线会匹配到

r := mux.NewRouter()
r.HandleFunc("/specific", specificHandler)
r.PathPrefix("/").Handler(catchAllHandler)
子路由器
// 主机
r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()
s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
// 路径
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)
静态文件
func main() {
    var dir string

    flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir")
    flag.Parse()
    r := mux.NewRouter()

    // http://localhost:8000/static/<filename>
    r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

    srv := &http.Server{
        Handler:      r,
        Addr:         "127.0.0.1:8000",
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
    }
    log.Fatal(srv.ListenAndServe())
}
注册网址
r := mux.NewRouter()
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
  Name("article")

// "/articles/go/42"
url, err := r.Get("article").URL("category", "go", "id", "42")


r := mux.NewRouter()
r.Host("{subdomain}.example.com").
Path("/articles/{category}/{id:[0-9]+}").
Queries("filter", "{filter}").
HandlerFunc(ArticleHandler).
Name("article")

// url.String() "http://news.example.com/articles/go/42?filter=mux"
url, err := r.Get("article").URL("subdomain", "news",
"category", "go",
"id", "42",
"filter", "mux")
钩子
package main

import (
	"fmt"
	"net/http"
	"strings"

	"github.com/go-mux/mux"
)

func handler(w http.ResponseWriter, r *http.Request) {
	return
}

func main() {
	r := mux.NewRouter()
	r.HandleFunc("/", handler)
	r.HandleFunc("/products", handler).Methods("POST")
	r.HandleFunc("/articles", handler).Methods("GET")
	r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT")
	r.HandleFunc("/authors", handler).Queries("surname", "{surname}")
	err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
		pathTemplate, err := route.GetPathTemplate()
		if err == nil {
			fmt.Println("ROUTE:", pathTemplate)
		}
		pathRegexp, err := route.GetPathRegexp()
		if err == nil {
			fmt.Println("Path regexp:", pathRegexp)
		}
		queriesTemplates, err := route.GetQueriesTemplates()
		if err == nil {
			fmt.Println("Queries templates:", strings.Join(queriesTemplates, ","))
		}
		queriesRegexps, err := route.GetQueriesRegexp()
		if err == nil {
			fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ","))
		}
		methods, err := route.GetMethods()
		if err == nil {
			fmt.Println("Methods:", strings.Join(methods, ","))
		}
		fmt.Println()
		return nil
	})

	if err != nil {
		fmt.Println(err)
	}

	http.Handle("/", r)
}
中间件 Middleware
func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        log.Println(r.RequestURI)
        next.ServeHTTP(w, r)
    })
}
r := mux.NewRouter()
r.HandleFunc("/", handler)
r.Use(loggingMiddleware)
处理CORS请求
package main

import (
	"net/http"
	"github.com/go-mux/mux"
)

func main() {
    r := mux.NewRouter()

    // 您必须为中间件指定OPTIONS方法匹配器来设置CORS标头
    r.HandleFunc("/foo", fooHandler).Methods(http.MethodGet, http.MethodPut, http.MethodPatch, http.MethodOptions)
    r.Use(mux.CORSMethodMiddleware(r))
    
    http.ListenAndServe(":8080", r)
}

func fooHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", "*")
    if r.Method == http.MethodOptions {
        return
    }

    w.Write([]byte("foo"))
}

完整示例:

package main

import (
    "net/http"
    "log"
    "github.com/go-mux/mux"
)

func YourHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Gorilla!\n"))
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/", YourHandler)
    log.Fatal(http.ListenAndServe(":8000", r))
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrMethodMismatch 当请求中的方法不匹配时返回,针对路由定义的方法。
	ErrMethodMismatch = errors.New("method is not allowed")
	// ErrNotFound 当没有找到匹配的路由时返回
	ErrNotFound = errors.New("no matching route was found")
)
View Source
var SkipRouter = errors.New("skip this router")

SkipRouter 从WalkFuncs返回一个SkipRouter值,walk将要下行到的路由器应该被跳过

Functions

func Vars

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

Vars 返回当前请求的路由变量(如果有)

Types

type BuildVarsFunc

type BuildVarsFunc func(map[string]string) map[string]string

BuildVarsFunc 自定义构建变量是否使用函数签名(可以在构建路由URL之前修改路由变量)

type MatcherFunc

type MatcherFunc func(*http.Request, *RouteMatch) bool

MatcherFunc 是自定义匹配器使用的函数签名

func (MatcherFunc) Match

func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool

Match 返回给定请求的匹配项

type MiddlewareFunc

type MiddlewareFunc func(http.Handler) http.Handler

func CORSMethodMiddleware

func CORSMethodMiddleware(r *Router) MiddlewareFunc

CORSMethodMiddleware 自动设置Access-Control-Allow-Methods响应头

func (MiddlewareFunc) Middleware

func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler

type Route

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

Route 存储匹配请求和构建url的信息

func CurrentRoute

func CurrentRoute(r *http.Request) *Route

CurrentRoute 返回当前请求匹配的路由(如果有)

func (*Route) BuildOnly

func (r *Route) BuildOnly() *Route

BuildOnly 将路由设置为永远不匹配:它只用于构建url。

func (*Route) BuildVarsFunc

func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route

BuildVarsFunc 添加要用于修改生成变量的自定义函数(在构建路由的URL之前)

func (*Route) GetError

func (r *Route) GetError() error

GetError 返回构建路由时产生的错误(如果有)。

func (*Route) GetHandler

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

GetHandler 返回路由的处理程序(如果有的话)

func (*Route) GetHostTemplate

func (r *Route) GetHostTemplate() (string, error)

GetHostTemplate returns 返回主机匹配规则

func (*Route) GetMethods

func (r *Route) GetMethods() ([]string, error)

GetMethods 返回路由匹配的方法

func (*Route) GetName

func (r *Route) GetName() string

GetName 返回路由的名称(如果有)

func (*Route) GetPathRegexp

func (r *Route) GetPathRegexp() (string, error)

GetPathRegexp 返回用于匹配路由路径的扩展正则表达式

func (*Route) GetPathTemplate

func (r *Route) GetPathTemplate() (string, error)

GetPathTemplate 返回用于构建的模板

func (*Route) GetQueriesRegexp

func (r *Route) GetQueriesRegexp() ([]string, error)

GetQueriesRegexp 对象匹配的扩展正则表达式

func (*Route) GetQueriesTemplates

func (r *Route) GetQueriesTemplates() ([]string, error)

GetQueriesTemplates 返回查询的模板

func (*Route) Handler

func (r *Route) Handler(handler http.Handler) *Route

Handler 为路由设置一个处理程序

func (*Route) HandlerFunc

func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route

HandlerFunc 为路由设置处理函数

func (*Route) Headers

func (r *Route) Headers(pairs ...string) *Route

Headers 为请求标头值添加匹配器 示例:

r := mux.NewRouter()
r.Headers("Content-Type", "application/json",
          "X-Requested-With", "XMLHttpRequest")

面的路由只有在两个请求报头值匹配的情况下才会匹配,如果值是一个空字符串,它将匹配设置了键的任何值

func (*Route) HeadersRegexp

func (r *Route) HeadersRegexp(pairs ...string) *Route

HeadersRegexp 受一个键/值对序列,其中值具有正则表达式 示例:

r := mux.NewRouter()
r.HeadersRegexp("Content-Type", "application/(text|json)",
          "X-Requested-With", "XMLHttpRequest")

只有当两个请求头都匹配两个正则表达式时,上面的路由才会匹配 如果值是一个空字符串,它将匹配设置了键的任何值 使用字符串锚的开始和结束符(^和$)来匹配精确的值

func (*Route) Host

func (r *Route) Host(tpl string) *Route

Host 为URL主机添加匹配器,它接受包含0个或多个URL变量的模板,这些变量用{}括起来 变量可以定义一个可选的regexp模式来匹配:

- {name} 匹配任何东西直到下一个点.

- {name:pattern} 匹配给定的regexp模式.

示例:

r := mux.NewRouter()
r.Host("www.example.com")
r.Host("{subdomain}.domain.com")
r.Host("{subdomain:[a-z]+}.domain.com")

在给定路由中,变量名必须是唯一的。它们可以被检索到 调用 mux.Vars(request).

func (*Route) Match

func (r *Route) Match(req *http.Request, match *RouteMatch) bool

Match 根据请求匹配路由

func (*Route) MatcherFunc

func (r *Route) MatcherFunc(f MatcherFunc) *Route

MatcherFunc 添加要用作请求匹配器的自定义函数

func (*Route) Methods

func (r *Route) Methods(methods ...string) *Route

Methods 为HTTP方法添加匹配器,它接受一个或多个方法的序列来匹配 如:"GET", "POST", "PUT"

func (*Route) Name

func (r *Route) Name(name string) *Route

Name 设置路由的名称,用于构建url,在路由上多次调用Name是错误的

func (*Route) Path

func (r *Route) Path(tpl string) *Route

Path 为URL路径添加匹配器 它接受包含0个或多个URL变量的模板,这些变量用{}括起来 模板必须以"/"开头 变量可以定义一个可选的regexp模式来匹配:

- {name} 匹配下一个斜杠之前的任何内容 - {name:pattern} 匹配给定的regexp模式

示例:

r := mux.NewRouter()
r.Path("/products/").Handler(ProductsHandler)
r.Path("/products/{key}").Handler(ProductsHandler)
r.Path("/articles/{category}/{id:[0-9]+}").
  Handler(ArticleHandler)

在给定路由中,变量名必须是唯一的 可通过 mux.Vars(request)调用

func (*Route) PathPrefix

func (r *Route) PathPrefix(tpl string) *Route

PathPrefix 为URL路径前缀添加一个匹配器见Route.Path()

func (*Route) Queries

func (r *Route) Queries(pairs ...string) *Route

Queries 为URL查询值添加匹配器 接受一个键/值对序列。值可以定义变量 示例:

r := mux.NewRouter()
r.Queries("foo", "bar", "id", "{id:[0-9]+}")

只有当URL包含定义的查询时,上面的路由才会匹配,如:?foo=bar&id=42 如果值是一个空字符串,它将匹配设置了键的任何值 变量可以定义一个可选的regexp模式来匹配 - {name} 匹配下一个斜杠之前的任何内容 - {name:pattern} 匹配给定的regexp模式

func (*Route) Schemes

func (r *Route) Schemes(schemes ...string) *Route

Schemes 为URL模式添加匹配器

func (*Route) SkipClean

func (r *Route) SkipClean() bool

SkipClean 跳过路径清洗功能

func (*Route) Subrouter

func (r *Route) Subrouter() *Router

Subrouter 为路由创建子路由器

只有当父路由匹配时,它才会走内部路由,如:

r := mux.NewRouter()
s := r.Host("www.example.com").Subrouter()
s.HandleFunc("/products/", ProductsHandler)
s.HandleFunc("/products/{key}", ProductHandler)
s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler)

如果主机不匹配,也不会到子路由器

func (*Route) URL

func (r *Route) URL(pairs ...string) (*url.URL, error)

URL 为路由构建一个URL,示例:

r := mux.NewRouter()
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
  Name("article")

获取url示例:

url, err := r.Get("article").URL("category", "technology", "id", "42")
"/articles/technology/42"

适用于主机变量:

r := mux.NewRouter()
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
  Host("{subdomain}.domain.com").
  Name("article")

// url.String() "http://news.domain.com/articles/technology/42"
url, err := r.Get("article").URL("subdomain", "news",
                                 "category", "technology",
                                 "id", "42")

结果url的模式将是传递给Schemes的第一个参数:

// url.String() "https://example.com"
r := mux.NewRouter()
url, err := r.Host("example.com")
             .Schemes("https", "http").URL()

路由中定义的所有变量都是必需的,它们的值也必须是必需的

func (*Route) URLHost

func (r *Route) URLHost(pairs ...string) (*url.URL, error)

URLHost 为路由构建URL的主机部分(路由必须定义了主机),参考 Route.URL()

func (*Route) URLPath

func (r *Route) URLPath(pairs ...string) (*url.URL, error)

URLPath 为路由构建URL的路径部分(路由必须定义了路径). 参考 Route.URL()

type RouteMatch

type RouteMatch struct {
	Route   *Route
	Handler http.Handler
	Vars    map[string]string

	// MatchErr 设置为适当的匹配错误,如果存在不匹配,则设置为ErrMethodMismatch
	MatchErr error
}

RouteMatch 保存匹配的路由信息

type Router

type Router struct {
	// 404
	NotFoundHandler http.Handler
	// 405不被允许
	MethodNotAllowedHandler http.Handler
	// contains filtered or unexported fields
}

Router 路由器

func NewRouter

func NewRouter() *Router

NewRouter 创建一个路由器实例

func (*Router) BuildVarsFunc

func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route

BuildVarsFunc 用自定义函数注册一条新的路由

func (*Router) Get

func (r *Router) Get(name string) *Route

Get 返回用给定名称注册的路由

func (*Router) Handle

func (r *Router) Handle(path string, handler http.Handler) *Route

Handle 使用url匹配器注册新路由

func (*Router) HandleFunc

func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,
	*http.Request)) *Route

HandleFunc 用匹配器为URL路径注册一个新路由。

func (*Router) Headers

func (r *Router) Headers(pairs ...string) *Route

Headers 用请求标头值匹配器注册一个新路由

func (*Router) Host

func (r *Router) Host(tpl string) *Route

Host 为URL主机注册一个新的路由匹配器

func (*Router) Match

func (r *Router) Match(req *http.Request, match *RouteMatch) bool

Match 根据路由器注册的路由匹配给定的请求,match参数被填充

func (*Router) MatcherFunc

func (r *Router) MatcherFunc(f MatcherFunc) *Route

MatcherFunc 用自定义匹配器函数注册一条新路由

func (*Router) Methods

func (r *Router) Methods(methods ...string) *Route

Methods 用HTTP方法的匹配器注册一个新路由

func (*Router) Name

func (r *Router) Name(name string) *Route

Name 注册一个带有名称的新路由

func (*Router) NewRoute

func (r *Router) NewRoute() *Route

NewRoute 注册空路由

func (*Router) Path

func (r *Router) Path(tpl string) *Route

Path 用匹配器为URL路径注册一个新路由

func (*Router) PathPrefix

func (r *Router) PathPrefix(tpl string) *Route

PathPrefix 用URL路径前缀的匹配器注册一个新路由

func (*Router) Queries

func (r *Router) Queries(pairs ...string) *Route

Queries 用URL查询值的匹配器注册一个新路由

func (*Router) Schemes

func (r *Router) Schemes(schemes ...string) *Route

Schemes 为URL方案的匹配器注册一个新路由

func (*Router) ServeHTTP

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

ServeHTTP 分派匹配路由中注册的处理器,当有匹配时,可以调用mux.Vars(request)

func (*Router) SkipClean

func (r *Router) SkipClean(value bool) *Router

SkipClean 清理path路径,默认为false

func (*Router) StrictSlash

func (r *Router) StrictSlash(value bool) *Router

StrictSlash 定义新路由的尾斜杠行为,默认值为false,子路由会继承此设置

func (*Router) Use

func (r *Router) Use(mwf ...MiddlewareFunc)

func (*Router) UseEncodedPath

func (r *Router) UseEncodedPath() *Router

UseEncodedPath 匹配经过编码的原始路径 如: "/path/foo%2Fbar/to" 会匹配到 "/path/{var}/to". 如果没被调用 "/path/foo%2Fbar/to" 匹配到 "/path/foo/bar/to"

func (*Router) Walk

func (r *Router) Walk(walkFn WalkFunc) error

Walk 遍历路由器及其所有子路由器,对每条路由调用walkFn 在树中。路径是按照添加的顺序进行遍历的。Sub-routers 深度优先

type WalkFunc

type WalkFunc func(route *Route, router *Router, ancestors []*Route) error

WalkFunc 是Walk访问的每条路由所调用的函数类型,每次调用时,都会给出当前路由和当前路由器以及指向当前路由的祖先路由列表

Jump to

Keyboard shortcuts

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