对外的api接口,最关注的是接参和回调,go的开发就我目前理解,大都是针对各种结构体的开发,这里做的是各种情况下参数接取
1.在initialize 下创建validator语言转换的配置文件validator.go
package initialize
import (
"fmt"
"reflect"
"strings"
"user_api/global"
"github.com/gin-gonic/gin/binding"
"github.com/go-playground/locales/en"
"github.com/go-playground/locales/zh"
ut "github.com/go-playground/universal-translator"
"github.com/go-playground/validator/v10"
en_translations "github.com/go-playground/validator/v10/translations/en"
zh_translations "github.com/go-playground/validator/v10/translations/zh"
)
func InitTrans(locale string) (err error) {
//修改gin框架中的validator引擎属性, 实现定制
if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
//注册一个获取json的tag的自定义方法
v.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" {
return ""
}
return name
})
zhT := zh.New() //中文翻译器
enT := en.New() //英文翻译器
//第一个参数是备用的语言环境,后面的参数是应该支持的语言环境
uni := ut.New(enT, zhT, enT)
global.Trans, ok = uni.GetTranslator(locale)
if !ok {
return fmt.Errorf("uni.GetTranslator(%s)", locale)
}
switch locale {
case "en":
err := en_translations.RegisterDefaultTranslations(v, global.Trans)
if err != nil {
return err
}
case "zh":
err := zh_translations.RegisterDefaultTranslations(v, global.Trans)
if err != nil {
return err
}
default:
err := en_translations.RegisterDefaultTranslations(v, global.Trans)
if err != nil {
return err
}
}
return
}
return
}
2.修改main.go ,main中添加如下代码
//4.语言转换
if err := initialize.InitTrans("zh"); err != nil {
panic(err)
}
3.在user_api下,创建validator目录,创建vaildator.go
package validator
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"net/http"
"strings"
"user_api/global"
"github.com/go-playground/validator/v10"
)
func removeTopStruct(fileds map[string]string) map[string]string {
rsp := map[string]string{}
for field, err := range fileds {
rsp[field[strings.Index(field, ".")+1:]] = err
}
return rsp
}
func HandleValidatorError(c *gin.Context, err error) {
errs, ok := err.(validator.ValidationErrors)
if !ok {
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"message": err.Error(),
})
zap.S().Errorf("[HandleValidatorError] 校验参数异常: %s", err.Error())
}
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"message": removeTopStruct(errs.Translate(global.Trans)),
})
return
}
5.实际使用,接值校验,创建api_structure目录,创建user.go文件,这个主要存储这个服务接取参数的结构
package api_structure
//创建用户数据接取数据结构
type AddUserForm struct {
Account string `form:"account" json:"account" binding:"required"`
PassWord string `form:"password" json:"password" binding:"required"`
UserName string `form:"username" json:"username" binding:"required"`
Departments string `form:"departments" json:"departments"`
Mobile string `form:"mobile" json:"mobile" binding:"required,min=8,max=14"`
Role int64 `form:"role" json:"role" binding:"required"`
Addr string `form:"addr" json:"addr"`
Email string `form:"email" json:"email"`
}
6.api编写,到api/user.go
package api
import (
"context"
"github.com/gin-gonic/gin"
"net/http"
fromData "user_api/api_structure"
"user_api/global"
proto "user_api/proto"
myvalidator "user_api/validator"
)
func AddUser(ctx *gin.Context) {
AddUserData := fromData.AddUserForm{}
if err := ctx.ShouldBind(&AddUserData); err != nil {
myvalidator.HandleValidatorError(ctx, err)
return
}
res, err := global.UserSrvClient.AddUser(context.TODO(), &proto.ResponseUserInfo{
Account: AddUserData.Account,
UserName: AddUserData.UserName,
PassWord: AddUserData.PassWord,
Departments: AddUserData.Departments,
Email: AddUserData.Email,
Role: AddUserData.Role,
Addr: AddUserData.Addr,
Mobile: AddUserData.Mobile,
})
if err != nil {
ctx.JSON(http.StatusForbidden,
gin.H{
"code": 200,
"msg": "no",
"data": AddUserData,
})
return
}
ctx.JSON(http.StatusOK,
gin.H{
"code": 200,
"msg": "ok",
"req": AddUserData,
"data": res,
},
)
}
func GetUserInfo(ctx *gin.Context) {
ctx.JSON(http.StatusOK,
gin.H{
"code": 200,
"total": "ok",
"accounts": "获取用户信息",
})
}
到这就基本上完成了,重启下这个服务
接口可以跑通了