go-gin-api 規劃目錄和參數驗證(二)

概述

首先同步下項目概況:



上篇文章分享了,使用 go modules 初始化項目,這篇文章我們分享:

    規劃目錄結構

    模型綁定和驗證

    自定義驗證器

    制定 API 返回結構

廢話很少說,我們開始吧。

規劃目錄結構

 php

  ├─ go-gin-api    
    │  ├─ app    
    │     ├─ config           //配置文件    
    │        ├─ config.go    
    │     ├─ controller       //控制器層    
    │        ├─ param_bind    
    │        ├─ param_verify    
    │        ├─ ...    
    │     ├─ model            //數據庫ORM    
    │        ├─ proto    
    │        ├─ ...    
    │     ├─ repository       //數據庫操做層    
    │        ├─ ...    
    │     ├─ route            //路由    
    │        ├─ middleware    
    │        ├─ route.go    
    │     ├─ service          //業務層    
    │        ├─ ...    
    │     ├─ util             //工具包    
    │        ├─ ...    
    │  ├─ vendor  //依賴包    
    │     ├─ ...    
    │  ├─ go.mod    
    │  ├─ go.sum    
    │  ├─ main.go //入口文件

 



上面的目錄結構是我自定義的,你們也能夠根據本身的習慣去定義。

controller 控制器層主要對提交過來的數據進行驗證,而後將驗證完成的數據傳遞給 service 處理。

在 gin 框架中,參數驗證有兩種:

一、模型綁定和驗證。

二、自定義驗證器。

其中目錄 param_bind,存儲的是參數綁定的數據,目錄 param_verify 存儲的是自定義驗證器。

接下來,讓我們進行簡單實現。

模型綁定和驗證

好比,有一個建立商品的接口,商品名稱不能爲空。

配置路由(route.go):

 git

  ProductRouter := engine.Group("")    
    {    
        // 新增產品    
        ProductRouter.POST("/product", product.Add)    
        // 更新產品    
        ProductRouter.PUT("/product/:id", product.Edit)    
        // 刪除產品    
        ProductRouter.DELETE("/product/:id", product.Delete)    
        // 獲取產品詳情    
        ProductRouter.GET("/product/:id", product.Detail)    
    }

 


參數綁定(param_bind/product.go):

 github

   type ProductAdd struct {    
        Name string `form:"name" json:"name" binding:"required"`    
    }

 


控制器調用(controller/product.go):

  數據庫

 if err := c.ShouldBind(&param_bind.ProductAdd{}); err != nil {    
        utilGin.Response(-1, err.Error(), nil)    
        return    
    }

 



我們用 Postman 模擬 post 請求時,name 參數不傳或傳遞爲空,會出現:

Key: 'ProductAdd.Name' Error:Field validation for 'Name' failed on the 'required' tag

這說明使用到了參數設置的 binding:"required"。

那麼還能使用 binding 哪些參數,有文檔嗎?

有。Gin 使用 go-playground/validator.v8 進行驗證,相關文檔:

https://godoc.org/gopkg.in/go-playground/validator.v8

接下來,我們實現一下自定義驗證器。

自定義驗證器

好比,有一個建立商品的接口,商品名稱不能爲空而且參數名稱不能等於 admin。

相似於這種業務需求,沒法 binding 現成的方法,須要咱們本身寫驗證方法,才能實現。

自定義驗證方法(param_verify/product.go)

json

    func NameValid (    
        v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,    
        field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,    
    ) bool {    
        if s, ok := field.Interface().(string); ok {    
            if s == "admin" {    
                return false    
            }    
        }    
        return true    
    }

 



參數綁定(param_bind/product.go):

api

    type ProductAdd struct {    
        Name string `form:"name" json:"name" binding:"required,NameValid"`    
    }

 


同時還要綁定驗證器:

 app

   // 綁定驗證器    
    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {    
        v.RegisterValidation("NameValid", param_verify.NameValid)    
    }

 


我們用 Postman 模擬 post 請求時,name 參數不傳或傳遞爲空,會出現:

Key: 'ProductAdd.Name' Error:Field validation for 'Name' failed on the 'required' tag

name=admin 時:

Key: 'ProductAdd.Name' Error:Field validation for 'Name' failed on the 'NameValid' tag

OK,上面兩個驗證都生效了!

上面的輸出都是在控制檯,能不能返回一個 Json 結構的數據呀?

能。接下來我們制定 API 返回結構。

制定 API 返回結構

 框架

   {    
        "code": 1,    
        "msg": "",    
        "data": null    
    }

 



API 接口的返回的結構基本都是這三個字段。

好比 code=1 表示成功,code=-1 表示失敗。

msg 表示提示信息。

data 表示返回的數據。

那麼,咱們怎麼在 gin 框架中實現它?

其實很簡單 基於 c.JSON() 方法進行封裝便可,直接看代碼。

 工具

   package util    
    import "github.com/gin-gonic/gin"    
    type Gin struct {    
        Ctx *gin.Context    
    }    
    type response struct {    
        Code     int         `json:"code"`    
        Message  string      `json:"msg"`    
        Data     interface{} `json:"data"`    
    }    
    func (g *Gin)Response(code int, msg string, data interface{}) {    
        g.Ctx.JSON(200, response{    
            Code    : code,    
            Message : msg,    
            Data    : data,    
        })    
        return    
    }

 



控制器調用(controller/product.go):

 post

  utilGin := util.Gin{Ctx:c}    
    if err := c.ShouldBind(&param_bind.ProductAdd{}); err != nil {    
        utilGin.Response(-1, err.Error(), nil)    
        return    
    }

 



我們用 Postman 模擬 post 請求時,name 參數不傳或傳遞爲空,會出現:

    {    
        "code": -1,    
        "msg": "Key: 'ProductAdd.Name' Error:Field validation for 'Name' failed on the 'required' tag",    
        "data": null    
    }

 

 

name=admin 時:

    {    
        "code": -1,    
        "msg": "Key: 'ProductAdd.Name' Error:Field validation for 'Name' failed on the 'NameValid' tag",    
        "data": null    
    }

 

OK,上面兩個驗證都生效了!

相關文章
相關標籤/搜索