大纲
- Beego 是什么
- 为什么写这个
- 如何指导
前几天我写了一个,觉得还是让使用者难以上手。尽管它是一款优秀的API 工具。
但我在编写API 的过程中发现几个问题:
- 编写繁琐:尽管会提示出关键字,但是不支持 yaml 自动换行,自动对齐等功能
- 保存不方便: 尽管可以到处yaml 或者json 格式的配置文件,但要是API 发生变更,又需要重新打开下载的包,或者在线版的Editor
- 不极客:Swagger 是给程序员使用的,但是单纯的配置文件,程序员不太喜欢,而是喜欢那种编程实现的API,比如在本地可以及时访问,即使是变更也能立马看到效果
好,基于上面三点。我进行了探索:
- 第一:使用Swagger 插件
我一直很喜欢JetBrains 旗下的开发工具,样样皆上精品。各种主流的编程语言都有对应的集成开发环境,即使是只使用其中的一款,插件丰富,也能实现其他编程语言的编程。
Settings --> Plugins --> Swagger Plugins || Swagger Codegen
下载上述两个插件,即可在本地编写yaml 格式的Swagger配置文件,左边配置,右边可视化。
这样可以本地实现配置文件的编写,实现API 的编写。
- 第二:使用Beego 框架
beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API、Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计灵感来源于 tornado、sinatra 和 flask 这三个框架,但是结合了 Go 本身的一些特性(interface、struct 嵌入等)而设计的一个框架。
其中一个功能是自动化文档,让用户快速的编写API。
即:可以编程实现API。
下面的文章即是:如何实现使用Beego + Swagger 快速开发API.
接着上回的文章 , 我在文章多次提出Http 请求包含哪些知识?
- Http 动作
- URL 路径
- Body 体
- Response 响应
即:根据不同的 Http 动作,访问URL 路径,定位资源,服务端根据请求,将资源进行返回给用户的这么一个过程。
- 前提:理解 Beego 框架
Beego 采用典型的MVC框架:即M(models)、V(views)和C(controllers)
- M 层定义数据,表及结构体等
- V 层定义可视化层,即前端展现出现的页面,这里我们只需下载Swagger即可使用前端文件
- C 层处理业务逻辑,比如API 中的POST,PUT,GET, DELETE 等
一个典型的Beego 框架的目录大概是这样的:
├── conf│ └── app.conf├── controllers│ ├── admin│ └── default.go├── main.go├── models│ └── models.go├── static│ ├── css│ ├── ico│ ├── img│ └── js└── views ├── admin └── index.tpl复制代码
使用Beego + Swagger 编写API 的过程中,我们只需关注这些文件:
-
routers 定义Http URL 路径
-
models 定义请求体Body 和响应 Response
-
controllers 处理Http 请求动作:POST、PUT、DELETE、GET等
-
使用的到的工具:
go get github.com/astaxie/beego
go get github.com/beego/bee
beego 即:beego 库文件,不懂环境配置看文章
bee 即: 命令行工具,这个很好理解,go 也有命令行工具,这些都是方便创建和管理相关项目的命令行(最近也在工作中开发一个命令行工具,有时间聊聊)
开始
- 创建API 项目
bee api apiTest
在 src (go项目环境变量下) 新建了一个apiTest 文件夹,里面默认存在一些默认的API 文件
- 自动下载Swagger文件,自动化文档,即可在本地浏览默认API: http://8080/swagger
bee run -gendoc=true -downdoc=true
生成的 API 文件目录大概这样:
├── conf│ └── app.conf├── controllers│ └── object.go│ └── user.go├── docs│ └── doc.go├── main.go├── models│ └── object.go│ └── user.go├── routers│ └── router.go└── tests └── default_test.go复制代码
各文件作用
- main.go 函数入口
- models 对应的API 中涉及的body 和 response
- routers 路由设置:即URL 路径
- controllers 对应URL 的动作发生和响应的处理
- app.conf 配置文件
主要处理:models 、contorlers 和 routers 三个文件。
核心思路:关注这三点:http 动作、请求、以及返回响应;无需关注具体的处理逻辑,一律使用 Fake 数据
示例:
实现下面这个例子:
例子:
POST /api/v1.0/designer/paas/{paasid}Request{ "git": { "addr":"ssh://ipaddr/path/.git", "branch":"master" }}Normal response codes: 201{ "passid":"xxxxx", "local_git":"ssh://localhost/paasdata/confcenter/{paasid}/pdmng/.git"}Error response codes: 400{ "desc": "error reason"}GET /api/v1.0/designer/paas/{paasid}?field=detailRequest: NoneResponse:201{ "passid":"xxxxx", "local_git":"ssh://localhost/paasdata/confcenter/{paasid}/pdmng/.git"}400{ "status": "no exist {paasid}"}PUT /api/v1.0/designer/paas/{paasid}Request:{ "git": { "addr":"ssh://ipaddr/path/.git", "branch":"master" }}Normal response codes: 201{ "passid":"xxxxx", "local_git":"ssh://localhost/paasdata/confcenter/{paasid}/pdmng/.git"}Error response codes: 400{ "status": "error reason"}DELETE /api/v1.0/designer/paas/{paasid}Request NoneResponse 201:{ "status": "success"}400:{ "status": "no exist the paasid"}复制代码
前面我们已经知道了,结合Beego 和 Swagger 编写API 的重点是在编写 models 和 controllers: models 编写参数、响应 即:定义各种各种的结构体和编写具体的函数
controllers 编写具体的http 动作请求和响应 即:定义具体的参数类型和响应值和类型等。
现在我们就以上例中的 get 方法讲述如何编写models 和 controller 。
GET /api/v1.0/designer/paas/{paasid}?field=detailRequest: NoneResponse:201{ "passid":"xxxxx", "local_git":"ssh://localhost/paasdata/confcenter/{paasid}/pdmng/.git"}400{ "status": "no exist {paasid}"}复制代码
request: 无
response: 分两种:成功和失败,响应值和状态码
则:models 层这样编写:
201 时的返回值信息type PaaSIdInfoResponse struct{ PaaSid: string `json:"paasid"` LocalGit: string `json:"local_git"`}400 时的返回值信息type StatusResponse struct{ Status string `json:"status"`}400 时也可以值定义成返回一个字符串信息。但本文不这么处理。定义函数:表示Get 方法触动的过程func GetStatusResponse(paasid string) *StatusResponse { if paasid == "" { return nil } return &StatusResponse{ Status: fmt.Sprintf("no exist %s", paasid), }}func GetSuccessResponse(paasid string) *PaaSIdInfo { return &PaaSIdInfo{ PaaSid: paasid, LocalInfo: fmt.Sprintf("ssh://localhost/paasdata/confcenter/%s/pdmng/.git", paasid), }}复制代码
则 controller 层:
回到 , 我们指出:全文分三个部分,一个是全局基本信息:比如Swagger 版本,介绍,BasePath 等; 核心是path 部分:一个是URL 路径,一个是Parameters 一个是Response .
Beego + Swagger 如何实现这些信息的呢?
Beego 靠编写注释来实现这些信息:
router.go 文件信息注释来实现全局信息:
// @APIVersion 1.0.0// @Title mobile API// @Description mobile has every tool to get any job done, so codename for the new mobile APIs.// @Contact astaxie@gmail.compackage routers复制代码
@APIVersion@Title@Description@Contact@TermsOfServiceUrl@License@LicenseUrl复制代码
填写关键字后面的内容即可改变全局信息。
controller 文件内的注释来实现path 中的Parameters 和 Response 等
// @Title getStaticBlock// @Description get all the staticblock by key// @Param key path string true "The email for login"// @Success 200 {object} models.ZDTCustomer.Customer// @Failure 400 Invalid email supplied// @Failure 404 User not found// @router /staticblock/:key [get]func (c *CMSController) StaticBlock() {}复制代码
@Title 表示描述函数信息@Description 表示较详细介绍函数信息@Param 表示描述API 动作中的参数:路径中的参数,传入的Body等@Success 表示描述API 正确处理时的返回信息和状态码@Failure 表示描述API 错误处理时的返回值信息和状态码@router 表示API 路径URL [] 表示该函数的动作类型:post、get、put、delete等复制代码
上例中的controller 这样写:
// @Title Get// @Description get paasid info from API// @Param paasid path string true "The paasid name"// @Param field query string true "field"// @Success 201 {object} models.PaaSIdInfo// @Failure 400 {object} models.StatusResponse// @router /paas/:paasid [get]func (p *PaaSController) Get() { paasid := p.Ctx.Input.Param(":paasid") if paasid != "" { data := models.GetSuccessResponse(paasid) p.Data["json"] = data } else { data := models.GetStatusResponse(paasid) p.Data["json"] = data } p.ServeJSON()}复制代码
其余类似:
要是看不懂,正确的做法应该是:
- 下载Beego
- 下载Beego 命令行工具 bee
- 创建API 项目:bee api apitest
- 首次运行:bee run -gendoc=true -downdoc=true
- 访问:http://127.0.0.1:8080/swagger 查看效果
- 阅读:controllers 、models 文件下的 go 文件源代码
总结
本文讲述使用Beego + bee + Swagger 实现的API 的编写。
核心在于理解:
- beego 架构的MVC 模式
- Http 请求的关键步骤:请求、响应模式
- 编写模型层和控制层
最后效果: