更多分享内容可访问我的个人博客
本文将通过一个简单的案例帮助初学者打通 beego api 开发流程。
环境配置
-
安装 golang,配置
GOPROXY
,GOPATH
,GOROOT
,启用 go module。 -
在 shell 配置文件中加入
export GOPATH="yourPath"
。并且将 GOPATH 中的 bin 目录加入 PATH。 -
安装 bee。
go install github.com/beego/bee/v2@latest
-
创建新项目。
bee api quickstart
go mod tidy
bee generate docs
项目结构与执行逻辑
beego 是一个典型的 MVC 架构。它的执行逻辑如下图所示。
当前创建的是 api 项目,没有前端部分。
相对应的项目目录如下所示。
运行项目
在项目目录下使用bee run -gendoc=true -downdoc=true
运行项目。第一次运行时会自动下载调试工具swagger
。
访问http://127.0.0.1:8080/swagger/
可以看到调试界面。
源码分析
Entry
首先来看入口文件main.go
package main
import (
_ "quickstart/routers"
beego "github.com/beego/beego/v2/server/web"
)
func main() {
if beego.BConfig.RunMode == "dev" {
beego.BConfig.WebConfig.DirectoryIndex = true
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
}
beego.Run()
}
main
函数中第一条语句是设置在 dev 运行模式下启动 swagger 调试器,这与项目主干无关,暂时不管它。
第二条语句调用了一个Run
方法,运行整个程序。那么到底是怎么运行的呢,看到一个关键的引入_ "quickstart/routers"
。这个包只引入了其中的 init 函数,我们去到routers/router.go
查看到底干了什么。
Routers
package routers
import (
"quickstart/controllers"
beego "github.com/beego/beego/v2/server/web"
)
func init() {
ns := beego.NewNamespace("/v1",
beego.NSNamespace("/object",
beego.NSInclude(
&controllers.ObjectController{
},
),
),
beego.NSNamespace("/user",
beego.NSInclude(
&controllers.UserController{
},
),
),
)
beego.AddNamespace(ns)
}
以上init
函数做的工作,简单地说,就是将不同的请求对应到不同的控制器。
本目录中还有另一个文件commentsRouter_controllers.go
。以下列出部分内容。
package routers
import (
beego "github.com/beego/beego/v2/server/web"
"github.com/beego/beego/v2/server/web/context/param"
)
func init() {
beego.GlobalControllerRouter["quickstart/controllers:UserController"] = append(beego.GlobalControllerRouter["quickstart/controllers:UserController"],
beego.ControllerComments{
Method: "Get",
Router: "/:uid",
AllowHTTPMethods: []string{
"get"},
MethodParams: param.Make(),
Filters: nil,
Params: nil})
}
看到quickstart/controllers:UserController
,这其实对应了 controllers 这一层的一个控制器。再看到Method: "Get"
,这是该控制器实现的一个方法。所以这个文件可以看作是注册控制器与函数。其余的配置暂时不管,重点关注Router: "/:uid"
。这个配置的意思是当有 Get 请求http://127.0.0.1:8080/v1/user/xxx
(可以直接用浏览器访问该地址)时,会执行控制器中的Get
函数。
xxx 可以任意但是必须有,这里写的 :uid 是在实现控制器方法的时候读取输入用的,不是指 xxx 必须是 :uid。
那么,至此便知道如何用不同的请求执行不同的函数了。
然后再去到 controllers/user.go
,查看这一层干了什么。
Controllers
package controllers
import (
"quickstart/models"
"encoding/json"
beego "github.com/beego/beego/v2/server/web"
)
// Operations about Users
type UserController struct {
beego.Controller
}
// @Title CreateUser
// @Description create users
// @Param body body models.User true "body for user content"
// @Success 200 {int} models.User.Id
// @Failure 403 body is empty
// @router / [post]
func (u *UserController) Post() {
var user models.User
json.Unmarshal(u.Ctx.Input.RequestBody, &user)
uid := models.AddUser(user)
u.Data["json"] = map[string]string{
"uid": uid}
u.ServeJSON()
}
// @Title GetAll
// @Description get all Users
// @Success 200 {object} models.User
// @router / [get]
func (u *UserController) GetAll() {
users := models.GetAllUsers()
u.Data["json"] = users
u.ServeJSON()
}
// @Title Get
// @Description get user by uid
// @Param uid path string true "The key for staticblock"
// @Success 200 {object} models.User
// @Failure 403 :uid is empty
// @router /:uid [get]
func (u *UserController) Get() {
uid := u.GetString(":uid")<