使用适配器简化golang gin框架开发

20 篇文章 4 订阅

我们在使用Gin框架时,可能在handler中有很多分支判断语句,就要写很多的ctx.Json来返回数据,这样用起来很麻烦,看起来也不美观。本文将使用一个适配器来简化Gin的数据响应。

比如,我们在使用Gin框架时,往往会这么写,在创建用户的handler中反复使用ctx.Json来返回数据,handler多了也会显得很烦。因此能不能实现一个handle,直接返回值就可以达到写出数据的目的呢。这时就可以使用适配器模式来进行优化一下了。


type User struct {
	Username string  `json:"username"`
	Password string  `json:"password"`
	Email    string  `json:"email"`
	PhoneNum string  `json:"phoneNum"`
}

type Response struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

func CreateUser(ctx *gin.Context) {
	var u User
	err := ctx.Bind(&u)
	if err != nil {
		ctx.Status(http.StatusBadRequest)
		return
	}

	// 查询数据库
	err = userService.AddUser(&u)
	if err != nil {
		ctx.JSON(http.StatusOK, &Response{
			Code:    1,
			Message: "Create user failed",
			Data:    nil,
		})
		return
	}

	ctx.JSON(http.StatusOK, &Response{
		Code:    0,
		Message: "Create user success",
		Data:    nil,
	})
}

优化后的代码:

首先我们定义一个通用的Response

package response

type resResult struct {
	Data    []interface{} `json:"data"`
	Status  uint32        `json:"status"`
	Message string        `json:"message"`
}

type Response struct {
	HttpStatus int
	R          resResult
}

// 为了提高效率我们可以使用一个Pool
var pool = sync.Pool{
	New: func() interface{} {
		return &Response{}
	},
}

// 定义自己的返回code
const (
	QuerySuccess uint32 = iota
	QueryFailed
)

var MessageForCode = map[uint32]string{
	QuerySuccess: "查询成功",
	QueryFailed:  "查询失败",
}


func NewResponse(status int, code uint32, data ...interface{}) *Response {
	response := pool.Get().(*Response)
	response.HttpStatus = status
	response.R.Status = code
	response.R.Message = MessageForCode[code]
	response.R.Data = data
	if len(data) == 0 {
		response.R.Data = make([]interface{}, 0)
	} else {
		response.R.Data = data
	}

	return response
}

func PutResponse(res *Response) {
	pool.Put(res)
}

func NewResponseOk(code uint32, data ...interface{}) *Response {
	return NewResponse(http.StatusOK, code, data...)
}

然后定义一个适配器:

type Handler func(ctx *gin.Context) *serialize.Response

func HandlerAdapter(h Handler) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		r := h(ctx)
		if r != nil {
			ctx.JSON(r.HttpStatus, &r.R)
		}

		serialize.PutResponse(r)
	}
}

然后就可以使用自己的handler来处理请求了:

在这里插入图片描述

上面的看起来是不是舒服多了。

注册handler时:

func Register(engine *gin.Engine) {
	engine.Post("/api/user", HandlerAdapter(controller.CreateUser))
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值