当前位置: 移动技术网 > IT编程>脚本编程>Go语言 > go-gin-api 规划目录和参数验证(二)

go-gin-api 规划目录和参数验证(二)

2019年11月10日  | 移动技术网IT编程  | 我要评论

概述

首先同步下项目概况:



上篇文章分享了,使用 go modules 初始化项目,这篇文章咱们分享:

    规划目录结构

    模型绑定和验证

    自定义验证器

    制定 api 返回结构

废话不多说,咱们开始吧。

规划目录结构

 

  ├─ 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 框架中,参数验证有两种:

1、模型绑定和验证。

2、自定义验证器。

其中目录 param_bind,存储的是参数绑定的数据,目录 param_verify 存储的是自定义验证器。

接下来,让咱们进行简单实现。

模型绑定和验证

比如,有一个创建商品的接口,商品名称不能为空。

配置路由(route.go):

 

  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):

 

   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)

    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):

    type productadd struct {    
        name string `form:"name" json:"name" binding:"required,namevalid"`    
    }

 


同时还要绑定验证器:

 

   // 绑定验证器    
    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):

 

  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,上面两个验证都生效了!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网