Beego脱坑(四)——Router

Router

路由的主要功能是实现从请求地址到实现方法,beego中封装了Controller,所以路由是从路径到ControllerInterface的过程。ControllerInterface 拥有很多方法,其中包括 InitPreparePostGetDeleteHead 等方法。

用户可以通过如下的方式进行路由设置:

beego.Router("/", &controllers.MainController{})

路由包里面我们看到执行了路由注册 beego.Router, 这个函数的功能是映射 URL 到 controller,第一个参数是 URL (用户请求的地址),这里我们注册的是 /,也就是我们访问的不带任何参数的 URL,第二个参数是对应的 Controller,也就是我们即将把请求分发到那个控制器来执行相应的逻辑。可以输入127.0.0.1:8080直接访问

我们也可以设置如下的路由:

beego.Router("/user", &controllers.UserController{})

我们可以输入127.0.0.1:8080/user访问

路由设置

beego 存在三种方式的路由:固定路由正则路由自动路由

最简单的 beego 路由由 URI 和闭包函数组成。如:

beego.Router("/user", &controllers.UserController{})

RESTful Controller 路由

在介绍这三种 beego 的路由实现之前先介绍 RESTful,我们知道 RESTful 是一种目前 API 开发中广泛采用的形式,beego 默认就是支持这样的请求方法,也就是用户 Get 请求就执行 Get 方法,Post 请求就执行 Post 方法。因此默认的路由是这样 RESTful 的请求方式。

固定路由

固定路由也就是全匹配的路由,如下所示:

beego.Router("/", &controllers.MainController{})
beego.Router("/admin", &admin.UserController{})
beego.Router("/admin/index", &admin.ArticleController{})
beego.Router("/admin/addpkg", &admin.AddController{})

如上所示的路由就是我们最常用的路由方式,一个固定的路由,一个控制器,然后根据用户请求方法不同请求控制器中对应的方法,典型的 RESTful 方式。

正则路由

为了用户更加方便的路由设置,beego 参考了 sinatra 的路由实现,支持多种方式的路由:

beego.Router(/api/?:id”, &controllers.RController{})

默认匹配 //例如对于URL”/api/123”可以匹配成功,此时变量”:id”值为”123

beego.Router(/api/:id”, &controllers.RController{})

默认匹配 //例如对于URL”/api/123”可以匹配成功,此时变量”:id”值为”123”,但URL”/api/“匹配失败

beego.Router(/api/:id([0-9]+), &controllers.RController{})

自定义正则匹配 //例如对于URL”/api/123”可以匹配成功,此时变量”:id”值为”123”

beego.Router(/user/:username([\\w]+), &controllers.RController{})

正则字符串匹配 //例如对于URL”/user/astaxie”可以匹配成功,此时变量”:username”值为”astaxie”

beego.Router(/download/*.*”, &controllers.RController{})

*匹配方式 //例如对于URL”/download/file/api.xml”可以匹配成功,此时变量”:path”值为”file/api”, “:ext”值为”xml”

beego.Router(/download/ceshi/*“, &controllers.RController{})

*全匹配方式 //例如对于URL”/download/ceshi/file/api.json”可以匹配成功,此时变量”:splat”值为”file/api.json”

beego.Router(/:id:int, &controllers.RController{})

int 类型设置方式,匹配 :id为int 类型,框架帮你实现了正则 ([0-9]+)

beego.Router(/:hi:string, &controllers.RController{})

string 类型设置方式,匹配 :hi 为 string 类型。框架帮你实现了正则 ([\w]+)

beego.Router(/cms_:id([0-9]+).html”, &controllers.CmsController{})

带有前缀的自定义正则 //匹配 :id 为正则类型。匹配 cms_123.html 这样的 url :id = 123

可以在 Controller 中通过如下方式获取上面的变量:

this.Ctx.Input.Param(":id")
this.Ctx.Input.Param(":username")
this.Ctx.Input.Param(":splat")
this.Ctx.Input.Param(":path")
this.Ctx.Input.Param(":ext")

自定义方法及 RESTful 规则

上面列举的是默认的请求方法名(请求的 method 和函数名一致,例如 GET 请求执行 Get 函数,POST 请求执行 Post 函数),如果用户期望自定义函数名,那么可以使用如下方式:

beego.Router("/",&IndexController{},"*:Index")

使用第三个参数,第三个参数就是用来设置对应 method 到函数名,定义如下

  • *表示任意的 method 都执行该函数
  • 使用 httpmethod:funcname 格式来展示
  • 多个不同的格式使用 ; 分割
  • 多个 method 对应同一个 funcname,method 之间通过 , 来分割
    以下是一个 RESTful 的设计示例:
beego.Router("/api/list",&RestController{},"*:ListFood")
beego.Router("/api/create",&RestController{},"post:CreateFood")
beego.Router("/api/update",&RestController{},"put:UpdateFood")
beego.Router("/api/delete",&RestController{},"delete:DeleteFood")

以下是多个 HTTP Method 指向同一个函数的示例:

beego.Router("/api",&RestController{},"get,post:ApiFunc")

以下是不同的 method 对应不同的函数,通过 ; 进行分割的示例:

beego.Router("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")

如果同时存在 * 和对应的 HTTP Method,那么优先执行 HTTP Method 的方法,例如同时注册了如下所示的路由:

beego.Router("/simple",&SimpleController{},"*:AllFunc;post:PostFunc")

那么执行 POST 请求的时候,执行 PostFunc 而不执行 AllFunc。自定义函数的路由默认不支持 RESTful 的方法,也就是如果你设置了

 beego.Router("/api",&RestController{},"post:ApiFunc") 

这样的路由,如果请求的方法是 POST,那么不会默认去执行 Post 函数。

自动匹配

用户首先需要把需要路由的控制器注册到自动路由中:

beego.AutoRouter(&controllers.ObjectController{})

然后完成ObjectController

package controllers
 
import (
	"github.com/astaxie/beego"
	"fmt"
)
 
type ObjectController struct {
	beego.Controller
}
 
func (this *ObjectController) GetFunc() {
	params := this.Ctx.Input.Params()
 
	for k, v := range params {
		fmt.Println(k  ,"=",v)
	}
	this.Ctx.WriteString(params[":splat"])//通过splat 输出所有值
 
}

beego 就会通过反射获取该结构体中所有的实现方法,你就可以通过如下的方式访问到对应的方法中:除了前缀两个 /:controller(控制器名称)/:method(函数名称) 的匹配之外,剩下的 url beego 会帮你自动化解析为参数,保存在 this.Ctx.Input.Params 当中。

如上面代码执行后,我们在浏览器中输入 http://127.0.0.1:8090/Object/GetFunc/1/2/3/4 得到如下结果:

*
:splat = 1/2/3/4
0 = 1
1 = 2
2 = 3
3 = 4

因为beego 会自动把参数转为小写 所以像 http://127.0.0.1:8090/oBjEct/GEtFunc/1/2/3/4 不匹配大小写输入也是可以的。

注解路由

从 beego 1.3 版本开始支持了注解路由,用户无需在 router 中注册路由,只需要 Include 相应地 controller,然后在 controller 的 method 方法上面写上 router 注释(// @router)就可以了,详细的使用请看下面的例子:

// CMS API
type CMSController struct {
    beego.Controller
}
 
func (c *CMSController) URLMapping() {
    c.Mapping("StaticBlock", c.StaticBlock)
    c.Mapping("AllBlock", c.AllBlock)
}
 
 
// @router /staticblock/:key [get]
func (this *CMSController) StaticBlock() {
 
}
 
// @router /all/:key [get]
func (this *CMSController) AllBlock() {
 
}

可以在 router.go 中通过如下方式注册路由:

beego.Include(&CMSController{})

beego 自动会进行源码分析,注意只会在 dev 模式下进行生成,生成的路由放在 “/routers/commentsRouter.go” 文件中。

这样上面的路由就支持了如下的路由:

  • GET /staticblock/:key
  • GET /all/:key

其实效果和自己通过 Router 函数注册是一样的:

beego.Router("/staticblock/:key", &CMSController{}, "get:StaticBlock")
beego.Router("/all/:key", &CMSController{}, "get:AllBlock")

同时大家注意到新版本里面增加了 URLMapping 这个函数,这是新增加的函数,用户如果没有进行注册,那么就会通过反射来执行对应的函数,如果注册了就会通过 interface 来进行执行函数,性能上面会提升很多。


作者:Clown95
来源:CSDN
原文:https://blog.csdn.net/yang731227/article/details/82253319
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(beego)