Go Gin 框架
說Gin是一個框架,不如說Gin是一個類庫或者工具庫,其包含了可以組成框架的元件。這樣會更好理解一點。
舉個?
下面的示例程式碼在這:github https://github.com/lpgyouxi/gogo
利用Gin組成最基本的框架。說到框架,我們可以先列舉下需要的(最基本)元件,主要四塊,以及下面的重點。
- 埠監聽
- 用於監聽請求,也就是服務
- 請求處理
- 請求分發
- 結果處理
- 路由
- 路由編寫
- 路由接入
- 業務處理
- 寫一個demo
好,開搞!
前提
* 你已經安裝好go環境,沒安裝的可以百度下,教程很多
* 你已經安裝了Gin,如果沒安裝,安裝命令:go get -u github.com/gin-gonic/gin
// Github上有https://github.com/gin-gonic/gin,大牛直接看這個不用看下面的了
* 建一個專案資料夾 gogo
* 初始化環境go mod init 模組名或者專案名
// 比如我把這個測試專案取名為 gogo ; go mod init gogo
埠監聽
埠監聽: 主要是監聽埠的訊息,提供服務入口。
檔案位置:~/gogo/server.go
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
server := gin.Default()
server.GET("/", func(c *gin.Context) {
param := c.DefaultQuery("name", "Guest") //注意:gin.Context 、引數獲取
c.JSON(http.StatusOK, gin.H{
"message": "hello 測試通過",
"data":param,
})
})
server.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
---------------------------
// 注意上面標識“注意”的行,後面可能會用到
// http://127.0.0.1:8080/?name=123456789
{
data: "123456789",
message: "hello 測試通過"
}
為了框架的整體連貫性,後面會對其優化。
請求處理
請求與返回可以看成業務處理的前置和後置部分,一般分為兩部分request和response,即 請求處理和返回處理,如下:
從這裡我將程式碼統一放到web的app目錄下,具體路徑如下
請求處理
~/gogo/app/distribute/request.go
package distribute
import (
"github.com/gin-gonic/gin"
)
/**
分配:連結上下文
link context
*/
// 定義一個接受引數的函式型別
type AppReqestFunc func(*AppReqest)
//定義引數結構體
type AppReqest struct {
*gin.Context
}
/*
定義引數賦予方法
*/
func Handle(r AppReqestFunc) gin.HandlerFunc {
// gin.HandlerFunc 理解為一種可操作的函式介面,匿名函式
return func(c *gin.Context) {
r(&AppReqest{c})
}
}
/*
定義引數獲取法
*/
//定義獲取get引數
func (params AppReqest) InputGet(paramName string) string {
return params.DefaultQuery(paramName, "")
}
/*
定義返回方法
*/
//成功返回
func (c *AppReqest) Success(data interface{}) {
c.JSON(Success(data))
}
Handle
定義了需要接受一個函式型別AppReqestFunc func(*AppReqest)
,其中引數滿足AppReqest
會返回一個gin.HandlerFunc
型別,這個型別適用於Gin的路由引數型別(即gin可呼叫)。
這裡Handle
可以做一些自定義的擴充套件。
返回處理
~/gogo/app/distribute/response.go
package distribute
import (
"github.com/gin-gonic/gin"
"net/http"
"reflect" // 物件操作的類
)
/**
成功返回,你可以建其它返回,如失敗、錯誤
Successful return, you can create other returns, such as failure and error
*/
func Success(data interface{}) (int, gin.H) {
ref := reflect.ValueOf(data)
if ref.IsNil() {
return http.StatusOK, gin.H{
"code": http.StatusOK,
"data": make(map[string]interface{}),
"message": "請求成功",
}
} else {
return http.StatusOK, gin.H{
"code": http.StatusOK,
"data": data,
"message": "請求成功",
}
}
}
一個返回格式,大致瞭解就行,可以自行豐富。
總結:上面兩個檔案分別是如何接受請求頭,和返回的格式,注意下引數賦予方法
這個可能不好理解,可以在紙上面畫畫,方便理解。
路由
路由編寫
為了以後的路由擴充套件,將server中的路由單獨存放,程式碼如下:
~/gogo/app/routes/api.go
package routes
import (
"github.com/gin-gonic/gin"
// "gogo/app/http" //業務模組
"gogo/app/distribute"
)
func Route(e *gin.Engine) {
//test
e.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "hello",
})
})
// 業務
// test := http.TestController{}
// e.GET("/test", distribute.Handle(test.Test))
// e.GET("/hello", distribute.Handle(test.Hello))
}
路由還可以分組,分檔案,這裡就不過多描述了,可以自己想想怎麼擴充套件。
上面的e.GET
可以按自己的需求進行編寫,這裡是舉了個?
路由接入
為了將路由使用到專案中,需要一箇中間銜接的檔案,實現方式為新增一個啟動檔案,將啟動服務時需要載入的檔案或功能載入進來。
~/gogo/app/boot/bootstrap.go
package boot
import (
"github.com/gin-gonic/gin"
"gogo/app/routes"
)
// 啟動入口
func Bootstrap(c *gin.Engine) {
SetRoute(c)
}
// 路由入口
func SetRoute(c *gin.Engine) {
routes.Route(c)
}
這裡將上面路由檔案載入進來了,現在改造服務檔案,加這個檔案載入進去。
package main
import (
"github.com/gin-gonic/gin"
// "net/http"
"gogo/app/boot"
)
func main() {
server := gin.Default()
boot.Bootstrap(server)
// server.GET("/", func(c *gin.Context) {
// param := c.DefaultQuery("name", "Guest")
// c.JSON(http.StatusOK, gin.H{
// "message": "hello 測試通過",
// "data":param,
// })
// })
server.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
和最前面的對比,可以看見,將路由替換為了:boot.Bootstrap(server)
,進行載入路由檔案。
業務處理
一個業務demo
注意前面路由檔案,有個路由如下
// 業務
// test := http.TestController{}
// e.GET("/test", distribute.Handle(test.Test))
// e.GET("/hello", distribute.Handle(test.Hello))
將其全部開啟;同時可以看到頭部的引入:"gogo/app/http"
;所以下面看看業務檔案怎麼編寫:
~/gogo/app/http/test.go
package httpimport ( "github.com/gin-gonic/gin" "gogo/app/distribute" "fmt")type TestController struct {}func (r *TestController) Hello(request *distribute.AppReqest) { fmt.Println("Ok"); request.Success(make([]int, 0));}func (r *TestController) Test(request *distribute.AppReqest) { request.JSON(200, gin.H{ "message": "hello 測試通過", })}
上面的Hello和Test就是業務程式碼塊,展示了返回的方式success
即是上面說到的返回處理。如果是複雜邏輯可以將詳細的業務程式碼引入到這裡,就不贅述了。
測試例子
http://127.0.0.1:8080/hello
-----------------------------------
{
code: 200,
data: [ ],
message: "請求成功"
}
新增方法
例子:
gogo/app/routes/api.go增加路由
// exp: get 、 param
e.GET("/get", distribute.Handle(test.TestGet))
gogo/app/http/test.go增加業務程式碼
func (r *TestController) TestGet(request *distribute.AppReqest) {
var data = []string{}
var name = request.InputGet("name")
data = append(data,name)
request.Success(data);
}
請求
http://127.0.0.1:8080/get?name=Lucy
-----------------------------------
{
code: 200,
data: [
"Lucy"
],
message: "請求成功"
}
至此,一個微型的例子就完成了。目錄結構如下:
|____go.mod
|____server.go
|____app
| |____boot
| | |____bootstrap.go
| |____distribute
| | |____response.go
| | |____request.go
| |____http
| | |____test.go
| |____routes
| | |____api.go
|____LICENSE
|____go.sum
|____README.md
結束
基礎的學習go web,深入的話還是需要實踐。
上面的程式碼在這:github
嗯,真的結束了!