大綱
- Beego 是什麼
- 為什麼寫這個
- 如何指導
前幾天我寫了一個Swagger 上手指南,覺得還是讓使用者難以上手。儘管它是一款優秀的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.
接著上回的文章Swagger 上手指南 , 我在文章多次提出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 庫檔案,不懂環境配置看文章 Go 語言專欄第一期
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=detail
Request: None
Response:
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 None
Response 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=detail
Request: None
Response:
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 上手指南, 我們指出:全文分三個部分,一個是全域性基本資訊:比如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.com
package 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 請求的關鍵步驟:請求、響應模式
- 編寫模型層和控制層
最後效果: