Gin 框架怎麼實現驗證請求參數和返回響應數據的函數?

大家好,我是 frank。「Golang 語言開發棧」公衆號作者。

01 介紹

在使用 Gin 框架開發時,入口函數通常需要支持驗證請求參數和返回響應數據。

我們可以將驗證請求參數和返回響應數據整合爲一個通用函數。

然後,結合響應數據返回中間件,實現通過一個函數,實現驗證請求參數和返回響應數據 的功能。

02 請求參數驗證和返回響應數據

首先,我們需要定義一個自定義結構體類型 Response,示例代碼:

type Response struct {
 Code int                    `json:"code"`
 Msg  string                 `json:"msg"`
 Data map[string]interface{} `json:"data"`
}

閱讀上面這段代碼,我們定義一個自定義結構體類型 Response,該結構體類型包含 3 個字段,分別是 CodeMsgData,並且分別定義了 json 標籤。

需要注意的是,字段 Data 使用的變量類型是 map[string]interface{},映射的 value 使用 interface{} 變量類型,可以支持任意類型的響應數據。

此外,我們還可以根據項目需求,添加其它字段,比如 TraceIdError 等。

返回響應數據

接下來,我們創建一個返回響應數據的函數,示例代碼:

func GetData(c *gin.Context) (data *Response) {
 value, exists := c.Get("data")
 if !exists {
  data = &Response{
   Code: http.StatusOK,
  }
  data.Data = make(map[string]interface{})
  c.Set("data", data)
  return
 }
 if data, exists = value.(*Response); !exists {
  data = &Response{Code: http.StatusInternalServerError}
  return
 }
 return
}

閱讀上面這段代碼,我們使用 Gin 框架的 gin.Context 的存儲數據,通過 SetGet 方法,設置和獲取數據。

需要注意的是,使用 gin.Context 存儲的數據是 interface{} 類型,所以,在我們使用該數據時,需要先通過斷言,檢查該數據的類型是否合法。

請求參數驗證

接下來,我們創建一個驗證請求參數和返回響應數據的函數 ValidatorAndReturn,示例代碼:

func ValidatorAndReturn(c *gin.Context, arg interface{}) (data *Response, err error) {
 data = GetData(c)
 err = c.ShouldBind(arg)
 if err != nil {
  return
 }
 return
}

閱讀上面這段代碼,我們定義一個函數,接收參數是 *gin.Context 類型的變量 c,和 interface{} 類型的變量 arg,返回結果是 *Response 類型的 data 和 error 類型的 err。

函數體中,包含自定義函數 GetDataShouldBind 方法。讀者朋友們,可以根據自己的項目,優化驗證請求參數的代碼。

需要注意的是,嚴格意義上講,此處 GetData 函數並未提供 Gin 框架入口函數自動返回響應數據的功能。我們需要通過中間件實現該功能。

03 響應數據返回中間件

最後,我們需要創建一箇中間件函數 ResponseReturn,使 Gin 框架的入口函數自動返回響應數據。

示例代碼:

// ResponseReturn middleware
func ResponseReturn() gin.HandlerFunc {
 return func(c *gin.Context) {
  data := GetData(c)
  c.Render(http.StatusOK, ReturnJson{Data: data})
 }
}

閱讀上面這段代碼,我們定義一箇中間件函數 ResponseReturn,使用 gin.ContextRender 方法,返回響應數據。

需要注意的是 Render 的第二個參數是 render.Render 類型。

源碼:

type Render interface {
    Render(http.ResponseWriter) error
    WriteContentType(w http.ResponseWriter)
}

閱讀 Gin 框架源碼,我們可以發現 render.Render 是一個接口類型,包含兩個方法,分別是 RenderWriteContentType

所以,我們定義了一個結構體 ReturnJson,並實現 render.Render 的兩個方法,示例代碼:

var contentType = []string{"application/json; charset=utf-8"}

type ReturnJson struct {
 Data interface{}
}

func responseContentType(w http.ResponseWriter, contentType []string) {
 header := w.Header()
 if val := header["Content-Type"]; len(val) == 0 {
  header["Content-Type"] = contentType
 }
}

func ResponseJson(w http.ResponseWriter, data interface{}) (err error) {
 responseContentType(w, contentType)
 bf := bytes.NewBuffer([]byte{})
 jsonEncoder := json.NewEncoder(bf)
 jsonEncoder.SetEscapeHTML(false)
 err = jsonEncoder.Encode(data)
 if err != nil {
  return
 }
 _, err = w.Write(bf.Bytes())
 if err != nil {
  return
 }
 return
}

func (r ReturnJson) Render(w http.ResponseWriter) (err error) {
 err = ResponseJson(w, r.Data)
 if err != nil {
  return
 }
 return
}

func (r ReturnJson) WriteContentType(w http.ResponseWriter) {
 responseContentType(w, contentType)
}

閱讀上面這段代碼,我們定義結構體類型的自定義類型 ReturnJson,並創建兩個方法 RenderWriteContentType,從而實現接口類型 render.Render,作爲 c.Render 的參數。

04 總結

本文我們介紹 Gin 框架怎麼實現驗證請求參數和返回響應數據的函數。

我們通過三個步驟完成,第一,創建返回響應數據的函數;第二,創建驗證請求參數和返回響應數據的整合函數;第三,創建返回響應數據的中間件函數。

本文所用到的代碼,我們在之前的文章中都介紹過,讀者朋友們如果有不明白的代碼,可以翻閱之前的文章。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/OR9NogjYAu2gGyeF8d_72Q