最近在研究Go,打算基於Go做點Web API,於是經過初步調研,打算用Beego這個框架,然後再結合其中提供的ORM以及Swagger的整合,可以快速搭建一個RESTful API的網站。
下面是具體做法:
1. 在Ubuntu中安裝Go 1.8
預設Ubuntu apt-get提供的是Go 1.6,而我們要用最新的Go 1.8需要執行以下操作:
1.1 新增apt-get源並重新整理
$ sudo add-apt-repository ppa:gophers/archive $ sudo apt-get update
1.2 安裝Go 1.8
$ sudo apt-get install golang-1.8
1.3 設定環境變數
等安裝完畢後,Go會被安裝到/usr/lib/go-1.8目錄。我們要執行go命令和建立自己專案的話,需要增加一些環境變數。
我們以後程式碼要放在當前使用者下的Go目錄下,需要先建立2個目錄:
$ mkdir -p ~/go/bin $ mkdir -p ~/go/src
然後設定當前使用者的環境變數:
vi ~/.profile
在結尾增加以下內容:
export GOROOT=/usr/lib/go-1.8 export PATH="$PATH:$GOROOT/bin" export GOPATH=$HOME/go export PATH="$PATH:$GOPATH/bin"
儲存後,重新重新整理環境變數
source ~/.profile
接下來我們驗證一下我們的Go版本,輸入
go version
我當前返回的是go version go1.8.1 linux/amd64說明我們的Go 1.8已經安裝成功
2. 下載Beego、Bee工具和MySQL驅動
Beego是一個非常適合Go初學者的Web框架,提供了很多的功能,有些人說他臃腫,不過對於我這個Go初學者來說,不在乎是否臃腫,而在乎是否快速解決問題,是否簡單。下面我們來安裝Beego,這個很簡單,只需要執行以下命令:
$ go get -u github.com/astaxie/beego
$ go get -u github.com/beego/bee
其中beego是框架的原始碼,而bee是一個快速建立執行Beego專案的工具。
我們的目標是要實現ORMapping,那麼連線資料庫是必不可少的,需要另外下載Go版的MySQL驅動:
$ go get github.com/go-sql-driver/mysql
這些通過go get下載下來的檔案都在~/go/src中,而bee工具是在~/go/bin中。
3. 建立api專案並執行
直接使用bee工具建立一個簡單的RESTful API專案是個不二的選擇,假設我們的專案名字叫testApi,那麼只需要執行:
bee api testApi
那麼程式就會建立對應的檔案在目錄~/go/src/testApi
接下來我們需要執行這個專案。首先切換到到專案資料夾,然後執行bee run命令:
cd ~/go/src/testApi bee run -gendoc=true -downdoc=true
這個時候我們可以看到系統已經執行在8080埠,我們切換到瀏覽器,訪問這個網站的Swagger地址:
http://192.168.100.129:8080/swagger/
就可以看到我們熟悉的Swagger介面了:
4. 修改程式碼,實現ORMapping
如果我們來到testApi專案資料夾,會看到類似MVC的結構,不過由於Web API不需要真正的View, 所有view資料夾被Swagger替換。下面我們要新建一個Student物件,並實現對Student增刪改查的Web API。
4.1 新建Student model和對應的表
我們可以先在MySQL中建立Student表:
CREATE TABLE `student` ( `Id` int(11) NOT NULL, `Name` varchar(10), `Birthdate` date , `Gender` tinyint(1) , `Score` int(11), PRIMARY KEY (`Id`) )
然後在model資料夾下新建Student.go檔案,增加Student物件:
type Student struct { Id int Name string Birthdate string Gender bool Score int }
4.2初始化ORM模組
我們要通過ORM來操作物件和資料庫,但是ORM需要初始化才能使用,我們需要在main.go檔案中增加以下內容:
import ( "github.com/astaxie/beego/orm" _ "github.com/go-sql-driver/mysql" ) func init() { orm.RegisterDriver("mysql", orm.DRMySQL) orm.RegisterDataBase("default", "mysql", "zengyi:123@tcp(127.0.0.1:3306)/testdb?charset=utf8") }
這裡需要注意的是資料庫連線字串和普通的寫法不一樣,要寫成如下格式:
使用者名稱:密碼@tcp(MySQL伺服器地址:埠)/資料庫名字?charset=utf8
4.3 提供資料庫查詢Student的方法
接下來就是資料庫訪問方法了。我們可以仿照user.go一樣,把方法都寫在Student.go檔案裡面。這是完整的Student.go檔案:
package models import ( "github.com/astaxie/beego/orm" "fmt" "time" ) type Student struct { Id int Name string Birthdate string Gender bool Score int } func GetAllStudents() []*Student { o := orm.NewOrm() o.Using("default") var students []*Student q:= o.QueryTable("student") q.All(&students) return students } func GetStudentById(id int) Student{ u:=Student{Id:id} o := orm.NewOrm() o.Using("default") err := o.Read(&u) if err == orm.ErrNoRows { fmt.Println("查詢不到") } else if err == orm.ErrMissPK { fmt.Println("找不到主鍵") } return u } func AddStudent(student *Student) int{ o := orm.NewOrm() o.Using("default") o.Insert(student) return student.Id } func UpdateStudent(student *Student) { o := orm.NewOrm() o.Using("default") o.Update(student) } func DeleteStudent(id int){ o := orm.NewOrm() o.Using("default") o.Delete(&Student{Id:id}) } func init() { // 需要在init中註冊定義的model orm.RegisterModel(new(Student)) }
4.4 建立StudentController對外提供Student的增加、刪除、修改、查詢一個、查詢所有的方法
這裡我們也可以仿照usercontroller,直接改寫成我們需要的StudentController.go。這是內容:
package controllers import "github.com/astaxie/beego" import ( "testApi/models" "encoding/json" ) type StudentController struct { beego.Controller } // @Title 獲得所有學生 // @Description 返回所有的學生資料 // @Success 200 {object} models.Student // @router / [get] func (u *StudentController) GetAll() { ss := models.GetAllStudents() u.Data["json"] = ss u.ServeJSON() } // @Title 獲得一個學生 // @Description 返回某學生資料 // @Param id path int true "The key for staticblock" // @Success 200 {object} models.Student // @router /:id [get] func (u *StudentController) GetById() { id ,_:= u.GetInt(":id") s := models.GetStudentById(id) u.Data["json"] = s u.ServeJSON() } // @Title 建立使用者 // @Description 建立使用者的描述 // @Param body body models.Student true "body for user content" // @Success 200 {int} models.Student.Id // @Failure 403 body is empty // @router / [post] func (u *StudentController) Post() { var s models.Student json.Unmarshal(u.Ctx.Input.RequestBody, &s) uid := models.AddStudent(&s) u.Data["json"] = uid u.ServeJSON() } // @Title 修改使用者 // @Description 修改使用者的內容 // @Param body body models.Student true "body for user content" // @Success 200 {int} models.Student // @Failure 403 body is empty // @router / [put] func (u *StudentController) Update() { var s models.Student json.Unmarshal(u.Ctx.Input.RequestBody, &s) models.UpdateStudent(&s) u.Data["json"] = s u.ServeJSON() } // @Title 刪除一個學生 // @Description 刪除某學生資料 // @Param id path int true "The key for staticblock" // @Success 200 {object} models.Student // @router /:id [delete] func (u *StudentController) Delete() { id ,_:= u.GetInt(":id") models.DeleteStudent(id) u.Data["json"] = true u.ServeJSON() }
這裡需要注意的是,函式上面的註釋是很重要的,有一定的格式要求,Swagger就是根據這些註釋來展示的,所以必須寫正確。
4.5 將StudentController註冊進路由
現在大部分工作已經完成,我們只需要把新的StudentController註冊進路由即可,開啟router.go,增加以下內容:
beego.NSNamespace("/student", beego.NSInclude( &controllers.StudentController{}, ), ),
當然對於系統預設的user和object,如果我們不需要,可以註釋掉。
4.6 執行並通過Swagger測試
我們的編碼已經完成。接下來使用bee命令來執行我們的專案:
bee run -gendoc=true -downdoc=true
我們就可以看到我們新的student Controller了。並且可以通過呼叫API來完成對student表的CRUD操作。