Go Gin 框架

說Gin是一個框架,不如說Gin是一個類庫或者工具庫,其包含了可以組成框架的元件。這樣會更好理解一點。

舉個

下面的示例程式碼在這:github

利用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

嗯,真的結束了!