26 ZH_Router
Lunny Xiao edited this page 6 years ago

Routers 路由

Tango支持4种形式的路由匹配规则:

  • 静态路由
tg.Get("/", new(Action))
tg.Get("/static", new(Action))

匹配 URL:/ 到 Action结构体的Get函数 匹配 URL:/static 到 Action结构体的Get函数

  • 命名路由
tg.Get("/:name", new(Action))
tg.Get("/(:name)", new(Action))
tg.Get("/:name1/:name2", new(Action))
tg.Get("/:name1-:name2", new(Action))
tg.Get("/(:name1)sss(:name2)", new(Action))
  • 通配路由
tg.Get("/*name", new(Action))
tg.Get("/ttt/*name", new(Action))
tg.Get("/sss(*name)", new(Action))

路由参数支持*通配符

  • 正则路由
tg.Get("/(:name.*)", new(Action))
tg.Get("/(:name[0-9]+)", new(Action))
tg.Get("/(:name1)-(:name2[0-9]+)", new(Action))

路由参数支持正则约束,不符合条件的参数会抛出404错误

也可以使用Route来绑定路由,形式更灵活

  • GET请求
t.Route("GET", "/", new(Action))
  • 自定义方法名
type Action struct {}
func (Action) MyPost() {}

t.Route("POST:MyPost", "/", new(Action))
  • 一次定义多个
t.Route([]string{"GET:MyGet", "POST"}, "/", new(Action))
  • 自定义多个
t.Route(map[string]string{"GET":"MyGet", "POST":"MyPost"}, "/", new(Action))

路由优先级

  • 静态路由和其它形式的路由都匹配时,静态路由优先,跟添加的顺序无关,如:
/abc
/(:name)

那么对于请求/abc,则/abc会匹配

  • 多个动态路由均匹配时,先出现静态部分的路由优先,如:
"/(:name1)/(:name1)abc"
"/(:name1)/abc(:name1)abc(:name2)abc"

那么对于请求/abc/abc123abc123abc,则/(:name1)/abc(:name1)abc(:name2)abc会匹配

  • 其它路由之间根据添加的顺序,先添加的优先。

路由参数

请求路径匹配后的参数可以通过*Context获得:

  • 命名路由和正则路由: ctx.Params().Get(":name")
  • 通配路由:ctx.Params().Get("*name")

绑定控制器

Tango 支持 5 种形式的函数或结构体方法作为执行体:

  • func()

  • func(http.ResponseWriter, *http.Request)

  • func(*tango.Context)

  • func(http.Response.Writer)

  • func(*http.Request)

  • struct.Get()

  • func()

t := tango.Classic()
t.Get("/", func() string {
    return "hello tango"
})
  • func(http.ResponseWriter, *http.Request)
t := tango.Classic()
t.Post("/", func(w http.ResponseWriter, *http.Request) {
    w.Write([]byte("hello tango"))
})
  • func(http.ResponseWriter)
t := tango.Classic()
t.Post("/", func(w http.ResponseWriter) {
    w.Write([]byte("hello tango"))
})
  • func(*http.Request)
t := tango.Classic()
t.Post("/", func(req *http.Request) string {
    return req.FormValue("key")
})
  • func(*tango.Context)
t := tango.Classic()
t.Get("/:name", func(ctx *tango.Context) {
    ctx.Write([]byte("hello " + ctx.Params().Get(":name")))
})
  • structs
type Action struct {}
func (a *Action) Get() string {
    return "haha"
}
t := tango.Classic()
t.Get("/:name", new(Action))

路由级别中间件

中间件可以是全局的,也可以应用到某个Group,也可以只针对某个Route,针对某个Route的中间件作为可选参数紧跟在Action之后即可。

t.Get("/:name", new(Action), MyMiddleware1(), MyMiddlewares2())