🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 1.注册控制器风格的路由 controller里处理http请求的方法必须是公共方法,**首字母大写**、**没有参数**、**没有返回值**。 方法接收器可以不是指针,并不强制。 ~~~ package main import "github.com/beego/beego/v2/server/web" type UserController struct { web.Controller } type IndexController struct { web.Controller } func (i *IndexController) Show() { i.Ctx.WriteString("this is index website") } func (u *UserController) HelloWorld() { u.Ctx.WriteString("hello, world") } func main() { web.AutoRouter(&UserController{}) web.AutoRouter(&IndexController{}) web.Run() } ~~~ ### Controller的名字 以上定义了UserController 和 IndexController,那它们的名字分别是User和Index。 大小写不敏感的时候,userController和 indexController也是合法的名字。 ### AutoRouter `AutoRouter`解析出来的路由规则由`RouterCaseSensitive`的值,`Controller`的名字和方法名字共同决定。 UserController 名字是User,方法是HelloWorld;如果`RouterCaseSensitive`为`true`, 那么`AutoRouter`会注册两个路由,`/user/helloworld/*`,`/User/HelloWorld/*`; 否则会注册一个路由,`/user/helloworld/*`;`RouterCaseSensitive`为Config结构体bool类型的字段。 ### AutoPrefix 使用`AutoPrefix`的时候,注册的路由符合`prefix/controllerName/methodName`这种样式。 ~~~ package main import "github.com/beego/beego/v2/server/web" type IndexController struct { web.Controller } func (i *IndexController) Show() { i.Ctx.WriteString("this is index website") } func main() { index := &IndexController{} web.AutoPrefix("api", index ) //http://localhost:8080/api/index/show web.Run() } ~~~ ## 2.注册函数式风格路由注册 ~~~ func main() { web.Get("/hello", func(ctx *context.Context) { ctx.WriteString("hello, world") }) web.Run() } ~~~ ## 3.Namespace 在注册路由的时候,需要按照一定的规律组织。 举例说明: * 整个应用分成两块,一个对安卓提供的API,一个对IOS,就划分成两个命名空间。 * 版本的划分,v1、v2、v3。 **代码示例:** ~~~ package main import ( "github.com/beego/beego/v2/server/web" "github.com/beego/beego/v2/server/web/context" ) type MainController struct { web.Controller } func (mc *MainController) Home() { mc.Ctx.WriteString("this is home") } type UserController struct { web.Controller } func (uc *UserController) Get() { uc.Ctx.WriteString("get user") } func Health(ctx *context.Context) { ctx.WriteString("health") } func main() { uc := &UserController{} ns := web.NewNamespace("/v1", web.NSCtrlGet("/home", (*MainController).Home), web.NSRouter("/user", uc), web.NSGet("/health", Health), ) web.AddNamespace(ns) web.Run() } ~~~ ### namespace的嵌套 ~~~ func main() { uc := &UserController{} // 初始化 namespace ns := web.NewNamespace("/v1", web.NSCtrlGet("/home", (*MainController).Home), web.NSRouter("/user", uc), web.NSGet("/health", Health), // 嵌套 namespace web.NSNamespace("/admin", web.NSRouter("/user", uc), ), ) //注册 namespace web.AddNamespace(ns) web.Run() } ~~~ ### namespace的条件执行 Beego的namespace提供了一种条件判断机制,只有符合条件的情况下,该namespace下的路由才会被执行。 ~~~ func main() { uc := &UserController{} ns := web.NewNamespace("/v1", web.NSCond(func(b *context.Context) bool { return b.Request.Header["x-trace-id"][0] != "" }), web.NSCtrlGet("/home", (*MainController).Home), web.NSRouter("/user", uc), web.NSGet("/health", Health), ) web.AddNamespace(ns) web.Run() } ~~~ 建议实现一个`filter`,代码理解性更高;该方法未来将移除。 ### Filter ~~~ func main() { uc := &UserController{} ns := web.NewNamespace("/v1", web.NSCond(func(b *context.Context) bool { return b.Request.Header["x-trace-id"][0] != "" }), web.NSBefore(func(ctx *context.Context) { fmt.Println("before filter") }), web.NSAfter(func(ctx *context.Context) { fmt.Println("after filter") }), web.NSCtrlGet("/home", (*MainController).Home), web.NSRouter("/user", uc), web.NSGet("/health", Health), web.NSNamespace("/admin", web.NSRouter("/user", uc), ), ) ns.Filter("before", func(ctx *context.Context) { fmt.Println("this is filter for health") }) web.AddNamespace(ns) web.Run() } ~~~