beego学习
安装
安装:
go get -u github.com/beego/bee/v2
go install github.com/beego/bee/v2
在~/.bash_profile添加可执行文件的环境变量:export PATH=/Users/dxm/go/bin:$PATH
快速开始 :快速开始一个web服务
router:指定url调用哪个控制器
controller:解析url请求的参数,调用业务代码,将参数传递到业务代码中。如果你的应用很简单,那么就直接写将业务代码写在controller中。您的逻辑里面存在着可以复用的东西,那么就抽取出来变成一个模块model。
model:可复用的业务代码
view:html页面 模板
路由注册
参考:
https://doc.meoying.com/beego/developing/web/router/ctrl_style/
router.go中进行路由注册。
控制器风格的路由AutoRouter:控制器名字和函数名字作为url
import "github.com/beego/beego/v2/server/web"
type UserController struct {
web.Controller
}
func (u *UserController) HelloWorld() { // 首字母大写,并且没有参数,没有返回值。
u.Ctx.WriteString("hello, world")
}
func main() {
web.AutoRouter(&UserController{})
web.Run()
}
说明:
- HelloWorld()首字母大写,并且没有参数,没有返回值。
- 方法接收器UserController优先使用指针,因为这符合 Beego 长期以来的实践,虽然实现的功能都是一样的。
- web.AutoRouter(&UserController{})解析UserController前的User为url的一部分,HelloWorld为另一部份,所以请求的url为 http://127.0.0.1:8080/user/helloworld 。url中是否区分大小写是由RouterCaseSensitive字段决定的,RouterCaseSensitive在Web 模块配置中有介绍。
AutoRouter内部是基于AutoPrefix实现的,我们可以直接使用AutoPrefix:
import (
"github.com/beego/beego/v2/server/web"
)
type UserController struct {
web.Controller
}
func (u *UserController) HelloWorld() {
u.Ctx.WriteString("Hello, world")
}
func main() {
// get http://localhost:8080/api/user/helloworld
// you will see return "Hello, world"
ctrl := &UserController{}
web.AutoPrefix("api", ctrl)
web.Run()
}
说明:
手动路由:CtrlXXX 一族来注册路由,即手动填写哪个url对应控制器中的哪个函数,并明确method。
AutoRoute或者AutoPrefix来注册路由,因为这两个都依赖于Controller的名字,也依赖于方法的名字。故使用CtrlXXX 一族来注册路由,即手动填写哪个url对应哪个函数。
CtrlXXX 一族来注册的话,如果使用指针,那么为(*UserController).HelloWord,非指针形式是UserController.HelloWord,后面一个看起来要清爽。
import (
"github.com/beego/beego/v2/server/web"
)
type UserController struct {
web.Controller
}
func (u UserController) GetUserById() {
u.Ctx.WriteString("GetUserById")
}
func (u UserController) UpdateUser() {
u.Ctx.WriteString("UpdateUser")
}
func (u UserController) UserHome() {
u.Ctx.WriteString("UserHome")
}
func (u UserController) DeleteUser() {
u.Ctx.WriteString("DeleteUser")
}
func (u UserController) HeadUser() {
u.Ctx.WriteString("HeadUser")
}
func (u UserController) OptionUsers() {
u.Ctx.WriteString("OptionUsers")
}
func (u UserController) PatchUsers() {
u.Ctx.WriteString("PatchUsers")
}
func (u UserController) PutUsers() {
u.Ctx.WriteString("PutUsers")
}
func main() {
// get http://localhost:8080/api/user/123
web.CtrlGet("api/user/:id", UserController.GetUserById)
// post http://localhost:8080/api/user/update
web.CtrlPost("api/user/update", UserController.UpdateUser)
// http://localhost:8080/api/user/home
web.CtrlAny("api/user/home", UserController.UserHome)
// delete http://localhost:8080/api/user/delete
web.CtrlDelete("api/user/delete", UserController.DeleteUser)
// head http://localhost:8080/api/user/head
web.CtrlHead("api/user/head", UserController.HeadUser)
// patch http://localhost:8080/api/user/options
web.CtrlOptions("api/user/options", UserController.OptionUsers)
// patch http://localhost:8080/api/user/patch
web.CtrlPatch("api/user/patch", UserController.PatchUsers)
// put http://localhost:8080/api/user/put
web.CtrlPut("api/user/put", UserController.PutUsers)
web.Run()
}
函数式风格路由注册(优先使用)。手动填写哪个url对应哪个函数,并明确method。
优先使用函数式风格的路由注册。最核心的理由就是这种注册风格最为便捷,并且贴近 Go 语言本身特性。目前的主流 Web 框架基本上都是支持这种注册风格。
func main() {
web.Get("/hello", func(ctx *context.Context) {
ctx.WriteString("hello, world")
})
web.Post("/post/hello", PostHello)
web.Run()
}
func PostHello(ctx *context.Context) {
ctx.WriteString("hello")
}
注解路由
参考:https://www.cnblogs.com/july-sunny/p/13763412.html
注册路由web.Router:
func main() {
ctrl := &MainController{}
// we register the path / to &MainController
// if we don't pass methodName as third param
// web will use the default mappingMethods
// GET http://localhost:8080 -> Get()
// POST http://localhost:8080 -> Post()
// ...
web.Router("/", ctrl)
// GET http://localhost:8080/health => ctrl.Health()
web.Router("/health", ctrl, "get:Health")
// POST http://localhost:8080/update => ctrl.Update()
web.Router("/update", ctrl, "post:Update")
// support multiple http methods.
// POST or GET http://localhost:8080/update => ctrl.GetOrPost()
web.Router("/getOrPost", ctrl, "get,post:GetOrPost")
// support any http method
// POST, GET, PUT, DELETE... http://localhost:8080/update => ctrl.Any()
web.Router("/any", ctrl, "*:Any")
web.Run()
}
上面这种做法已经不再使用了,从 beego 1.3 版本开始支持了注解路由,用户无需在 router 中注册路由,只需要 Include 相应地 controller,然后在 controller 的 method 方法上面写上 router 注释(// @router)就可以了,详细的使用请看下面的例子:
package controllers
import "github.com/beego/beego/v2/server/web"
// CMS API
type CMSController struct {
web.Controller
}
func (c *CMSController) URLMapping() {
c.Mapping("StaticBlock", c.StaticBlock)
c.Mapping("AllBlock", c.AllBlock)
}
// @router /staticblock/:key [get]
func (u *CMSController) StaticBlock() {
u.Ctx.WriteString("StaticBlock")
}
// @router /all/:key [get]
func (u *CMSController) AllBlock() {
u.Ctx.WriteString("AllBlock")
}
可以在 router.go 中通过如下方式注册路由:
beego.Include(&CMSController{})
使用命令bee generate routers
,将注释转换为具体的代码。beego 自动会进行源码分析,注意只会在 dev 模式下进行生成,生成的路由放在 “/routers/commentsRouter.go” 文件中。
同时大家注意到新版本里面增加了 URLMapping 这个函数,这是新增加的函数,用户如果没有进行注册,那么就会通过反射来执行对应的函数,如果注册了就会通过 interface 来进行执行函数,性能上面会提升很多。
查看已注册路由
命名空间
func main() {
uc := &UserController{}
// 创建 namespace
ns := web.NewNamespace("/v1",
web.NSCtrlGet("/home", (*MainController).Home),
web.NSRouter("/user", uc),
web.NSGet("/health", Health),
)
//注册 namespace
web.AddNamespace(ns)
web.Run()
}
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")
}
在我们启动服务器之后,分别访问下面三个地址:
- GET http://localhost:8080/v1/home
- GET http://localhost:8080/v1/user
- GET http://localhost:8080/v1/health
不管是函数式路由注册 还是 控制器路由注册,对于namespace来说都是可以的。整体规律就是多了NS这个前缀。
其他直接参考官方文档:
- namespace 嵌套:web.NSNamespace
- namespace 的条件执行:只有在符合条件的情况下,路由对应函数才会执行。如我们希望用户的请求的头部里面一定要带上一个x-trace-id才会被后续的请求处理。(不推荐使用,推荐使用Filter)
- Filter:过滤请求,但是我还不明白web.NSBefore或者web.NSAfter分别在什么时候会被运行。
Filter过滤器
Beego+MySQL搭建 Restful API 项目及API文档自动化
直接参考Beego+MySQL搭建 Restful API 项目及API文档自动化,但是需要注意如下点:
- 需要使用命令
bee generate routers
生成路由。参考:使用Beego创建API项目并自动化文档 - 在发送http请求时,需要注意请求字段的首字母大小写的问题。因为go语言中首部大写代表外部可访问,如果请求字段的首字母不大写,可能会导致请求返回404。
swagger
http://localhost:8080/swagger/ 不能选择请求发送的协议http或https,通过观察官方提供的配置文件:https://petstore.swagger.io/v2/swagger.json ,可以看出来我们的配置文件缺少了字段:"schemes": ["https","http"]
。然后我们通过beego生成swagger.json的源码可以看出来,只需要在router.go的开头添加如下注释就可以了:// @Schemes http,https
参数的开头需要大写,不然可能会出错误。