概述

首先同步下项目概况:

上篇文章分享了,使用 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,上面两个验证都生效了!

源码地址

https://github.com/xinliangnote/go-gin-api

go-gin-api 系列文章

[系列] go-gin-api 规划目录和参数验证(二)的更多相关文章

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

    概述 首先同步下项目概况: 上篇文章分享了,使用 go modules 初始化项目,这篇文章咱们分享: 规划目录结构 模型绑定和验证 自定义验证器 制定 API 返回结构 废话不多说,咱们开始吧. 规 ...

  2. .net core api 对于FromBody的参数验证

    前言 在framework的mvc中,经常会使用 Model.State . ModelState.IsValid 配合着特性进行参数验证,通过这种方式可以降低controller的复杂度,使用方便. ...

  3. MVC之参数验证(二)

    MVC内部针对这此验证是如何实现的咧???现在我们就来分析一下这此验证的背后故事.... 1.ModelValidator与ModelValidatorProvider 虽然Model绑定方式的因绑定 ...

  4. ASP.NET Web API 2 之参数验证

    Ø  前言 目前 C# 比较流行使用 ASP.NET Web API 来承载 Web 接口,提供与客户端之间的数据交互,现在的版本已经是 2.0 了.既然是接口就少不了对输入参数的验证,所以本文主要探 ...

  5. Gin框架 - 项目目录

    概述 今天给大家分享,在 API 端使用 Gin 框架时,项目的目录. 目录 ├─ Project Name │ ├─ config //配置文件 │ ├── ... │ ├─ controller ...

  6. 【quickhybrid】API规划

    前言 当一切就绪后,就要开始进行API规划,这一块是整个Hybrid框架中非常重要的内容,毕竟对于前端页面来说,只会通过JS API来调用功能. 基本上,API调用起来是否方便简洁影响着整个体验. 这 ...

  7. 智能合约语言 Solidity 教程系列8 - Solidity API

    这是Solidity教程系列文章第8篇介绍Solidity API,它们主要表现为内置的特殊的变量及函数,存在于全局命名空间里. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应 ...

  8. [译]C# 7系列,Part 8: in Parameters in参数

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/01/08/c-7-series-part-8-in-parameters/ 背景 默认情况下,方法参数 ...

  9. openresty开发系列11--openresty的api入门

    openresty开发系列11--openresty的api入门 1)ngx_lua模块的hello world编辑nginx下conf配置文件nginx.conf# vi nginx.conf在se ...

随机推荐

  1. 题解 P3126 【[USACO15OPEN]回文的路径Palindromic Paths】

    P3126 [USACO15OPEN]回文的路径Palindromic Paths 看到这题题解不多,蒟蒻便想更加通俗易懂地分享一点自己的心得,欢迎大佬批评指正^_^ 像这种棋盘形的两边同时做的dp还 ...

  2. C#7.0 新增功能

    连载目录    [已更新最新开发文章,点击查看详细] C# 7.0 向 C# 语言添加了许多新功能 01 out 变量 支持 out 参数的现有语法已在此版本中得到改进. 现在可以在方法调用的参数列表 ...

  3. [leetcode] 96 Unique Binary Search Trees (Medium)

    原题 字母题 思路: 一开始妹有一点思路,去查了二叉查找树,发现有个叫做卡特兰数的东西. 1.求可行的二叉查找树的数量,只要满足中序遍历有序. 2.以一个结点为根的可行二叉树数量就是左右子树可行二叉树 ...

  4. c实现哲学家进餐问题。WINDOWS下。

    // 解决哲学家就餐问题// 每个哲学家可用一个线程来模拟.// 设有5个哲学家,5只筷子,每个哲学家吃饭时间为一个随机值,哲学家吃饭后的思考时间也是一个随机值.#include <Window ...

  5. 【CodeForces - 357B】Flag Day(水题)

    Flag Day Descriptions 小G请你对 n 个点进行染色,可选的颜色有三种:白.红.蓝,并使得给定的 m 个三元组中,每个点的颜色各不相同. 因为你可能不会三分图匹配,于是小G给出了更 ...

  6. 【MySQL】(二)InnoDB存储引擎

    InnoDB是事务安全的MySQL存储引擎,设计上采用了类似于Oracel数据库的架构.通常来说,InnoDB存储引擎是OLTP应用中核心表的首选存储引擎.同时,也正是因为InnoDB的存在,才使My ...

  7. php 常用函数总汇

    php 使用命令行函数exec($sql,$result,$status); $sql 命令   $result  返回东西  $status成功与否的状态 例如: php使用命令行去执行数据库备份( ...

  8. 【iOS】设置 rootViewController

    iOS 开发中,rootViewController 经常用到,示例代码如下: self.window = [[UIWindow alloc] initWithFrame:[UIScreen main ...

  9. 一文了解:Redis事务

    Redis事务 事务提供了一种"将多个命令打包,一次性提交并按顺序执行"的机制,提交后在事务执行中不会中断.只有在执行完所有命令后才会继续执行来自其他客户的消息. Redis中的使 ...

  10. Linux基础管道管理

    一.I/O重定向 标准输入,标准输出,标准错误 file descriptors (FD, 文件描述符或Process I/O channels); 进程使用文件描述符来管理打开的文件 [root@l ...