本期內容是承接上期已經作好了登錄界面來寫的,不過本期是以golang爲主,可能須要你們把最基本的語法結構熟悉一下:菜鳥教程。這樣的話方便展開,天然而然的,本篇也是直接實戰爲主。此次須要依賴mysql,這個必須安裝,redis最好也安裝一下,之後會用到。html
這裏我打算啓動一個go的web application,那麼不少人的話都會本身從頭開始,不過這的確有點麻煩,網上其實不少大佬寫了一些腳手架,這裏我打算直接使用bydmm大佬的singo項目來開發,能夠看他的B站空間的系列教程:bydmm的我的空間。前端
因此首先在github把項目弄下來把:mysql
git clone https://github.com/Gourouting/singo.gitios
而後把項目文件夾目錄改稱本身的項目名稱把,就是把singo這個文件夾名字給改了,而後對應裏面的全部文件import都須要把singo改爲你的項目名稱。git
咱們能夠順便看一看項目結構,說明一下:
github
這些文件夾的名字都很明顯暴露意圖,這裏我打算暫時不一個個去講,由於這裏我打算說一些全部go項目應該都有的基礎東西,就是main.go。若是學過編程都明白,有且只有一個程序的入口,所以這個入口就是main.go,而且他只須要知足他的package是main,而且有一個func main()就能夠了:golang
package main func main() { }
這個腳手架他的環境配置使用.env來配置的,他也有一個.env exmaple,若是你想知道在哪裏實現的能夠看conf文件夾下面的conf.go,就是經過.env設置項目下的環境變量,而後在conf.go獲取而已,因此你修改一下文件名和把MYSQL_DSN修改爲本身的便可,若是不懂DSN的,能夠參考以下格式寫:web
username:password@protocol(address)/dbname?param=value
一個例子,由於默認的localhost:3306,能夠不用寫protocol字段
root:123456@/ysyh?charset=utf8&parseTime=True&loc=Localajax
go mod在這裏面是包管理器,在第一篇應該已經配好了goproxy和go111module,這個包管理器在現在版本很牛逼,你只須要作2件事情就能夠完成,爲了演示,咱們先把原來項目中的go.mod和go.sum給刪了,而後在shell輸入:redis
go mod init your_projectname
這樣你就弄好了go mod,以後你在運行項目的時候他會自動檢測你缺乏的依賴,而且安裝,你能夠直接試一試:
go run main.go
原本你只有一行的go.mod文件多了一堆依賴聲明,而且能夠運行項目。
後端第一件事是作接收請求,只有你能接受了請求,而且把他發到對應的地址纔有接下來的操做,因此咱們從路由看起。對於gin的路由,官方已經寫的很清楚了,在項目裏面就是server下的router.go,下面是關鍵的幾個代碼
func NewRouter() *gin.Engine { r := gin.Default() r.Use(middleware.Cors()) v1 := r.Group("/api/v1") { v1.POST("ping", api.Ping) auth := v1.Group("") auth.Use(middleware.AuthRequired()) { auth.GET("user/me", api.UserMe) } } }
我只截取了幾個知識點,首先 gin.Default()就是路由了,你直接r.Run(":port")就能夠直接在該端口上執行該路由。
接下來有個r.Use,這個是中間件的意思,中間件其實就是到你路由的方法前,他會作這個方法裏面的內容,例如例子中的Cors,由於我幾乎全部的請求都要作Cors,因此我不可能在每一個方法裏面都寫一遍這段代碼,所以咱們放在中間件裏面就省事了。能夠看一下gin的middlerware的格式:
import( "github.com/gin-contrib/cors" ) func Cors() gin.HandlerFunc { config := cors.DefaultConfig() return cors.New(config) }
拿Cors爲例子,只是把一個gin.HandlerFunc傳入Use方法裏面就能夠實現中間件註冊。
Group方法,其實Group方法就是把他下面的地址加上一段地址,例如上例子,v1下面的post方法呢,他的地址就是/api/v1/ping,調用的三api.ping這個方法。其實單看這個功能感受也通常,可是能夠看一下下面的auth的例子,他在auth下面直接Use,作了個登錄認證,因此在auth下面的地址都有一個middlerware,沒有登錄的都沒辦法訪問。所以分組以後能夠給組內成員加上middlerware,這樣就能夠節省不少代碼量。
路由以後呢,就會到達你想要處理這個請求的函數,我直接拿註冊爲例子來講明。
func UserRegister(c *gin.Context) { var service service.UserRegisterService if err := c.ShouldBind(&service); err == nil { res := service.Register() c.JSON(200, res) } else { c.JSON(200, ErrorResponse(err)) } }
這個就是註冊的處理函數,可是這個是這個腳手架作了封裝的,可是已經有靈魂了。首先能夠函數有個參數進來,是gin.Context指針的值。Context顧名思義的上下文,其實就是請求的cookie,headers,content之類的。因此咱們請求的信息都要從這裏面拿到。
以後有個這個c.ShouldBind(&service),這個意思是能夠對請求的內容作一個驗證,若是符合service這個strcut呢,他就告訴你請求的內容是沒有問題的,這裏能夠看一看這個struct的寫法
type UserRegisterService struct { Email string `form:"email" json:"email" binding:"required,email"` UserName string `form:"user_name" json:"user_name" binding:"required,min=5,max=30"` Password string `form:"password" json:"password" binding:"required,min=8,max=40"` PasswordConfirm string `form:"password_confirm" json:"password_confirm" binding:"required,min=8,max=40"` }
除了最後的字段應該均可以看得懂的。就是最後面有段內容,gin能夠讀取到那裏,而且根據這裏的內容去判斷傳入的參數是否有問題,能夠看一下Email這個例子,他要求前段能夠用form提交或者json提交,他對應的字段是email,而且後面有個binding,這個是驗證的規則了,required表明他必須存在,第二個email是表明他是一個email格式的文本。
最後呢,咱們處理完了就要返回結果了,這裏直接c.JSON就能夠以json的格式返回了。
後端操做不可避免要與數據庫交互的,因此這裏數據庫操做也是很重要的,咱們這裏用到的數據庫叫作gorm,能夠看看gorm官方文檔。不過gorm只支持mysql,PostgreSQL和Sqlite3,其餘的數據庫可能要用別的orm。這裏能夠在model下init.go看到數據庫的基本操做
func Database(connString string) { db, err := gorm.Open("mysql", connString) if err != nil { util.Log().Panic("鏈接數據庫不成功", err) } //設置鏈接池 //空閒 db.DB().SetMaxIdleConns(50) //打開 db.DB().SetMaxOpenConns(100) //超時 db.DB().SetConnMaxLifetime(time.Second * 30) migration() }
我這裏也是把跟數據庫連接比較重要的代碼拿出來了,這裏用單例我就沒貼了。首先怎麼去連接數據庫,就是gorm.Open就完事了,而後第一個參數是數據庫種類,第二個是DSN,DSN上面已經講過了。
以後呢咱們就要設置一些參數,上面也寫的很清楚了,最後有個migration,這個是gorm的很厲害的功能,他能夠自動的去生成表和修改表結構。其實就是DB.AutoMigrate這個方法,每次運行的時候,他都會先去把裏面的struct加入到數據庫中,例如這裏的user表,就是用以下的stcut自動遷移:
// User 用戶模型 type User struct { gorm.Model UserName string PasswordDigest string Email string Status string Avatar string `gorm:"size:1000"` }
這裏面的gorm.Model是這樣的,這裏面可能會涉及到gorm的軟刪除的內容,因此建議加上gorm.Model在你任意的表結構中:
type Model struct { ID uint `gorm:"primary_key"` CreatedAt time.Time UpdatedAt time.Time DeletedAt *time.Time `sql:"index"` }
咱們已經把最基本的後端邏輯給弄懂了,~雖然沒有弄實現邏輯~。可是咱們Vue怎麼給後端發請求?可能懂得人應該知道是ajax了,在Vue裏面的話你們經常使用的是axios,是基於Promise機制的,首先能夠安裝一下。
npm install axios
而後呢在main.js裏面加上(其中第二行是爲了防止作Cors的時候出問題):
import axios from 'axios';
axios.defaults.withCredentials=true
Vue.prototype.$axios = axios;
以後咱們在咱們的項目文件作請求就能夠:
this.$axios.get("http://127.0.0.1:3000/api/v1/user/me").then((res) => { //todo }).catch(err => { //todo }).finally(() => { })
若是是post請求就在後面把請求的參數加上去。這個請求發送以後若是正確了,就會到then裏面,結果就是用一個變量去接受便可。出現問題就能夠catch錯誤,最後也能夠用finally,這個函數無論成功與否都會去作。