Go Fiber中设计web响应封装

184 阅读2分钟

场景痛点

我们请求的时候一般来说都有状态码,和返回的message.但是很多时候我们不用关心返回的提示信息,如果没有封装的情况。就麻烦了,要自己设置状态码设置消息内容非常不方便,所以要封装。下面封装以fiber框架为示例展开,其他框架类似。

response.go

package api

import (
	"reflect"

	"github.com/gofiber/fiber/v2"
)


type MyCtx struct {
	*fiber.Ctx
	Msg  string
	Code int
}

func AppResult(c *fiber.Ctx) *MyCtx {
	myCtx := c.Locals("myctx").(*MyCtx)
	return myCtx
}

func (c *MyCtx) Success(params ...interface{}) error {
	c.Code = 200
	c.Msg = "success"
	return c.judge(params)
}

func (c *MyCtx) Fail(params ...interface{}) error {
	c.Code = 400
	c.Msg = "fail"
	return c.judge(params)
}

func CtxMiddleware(c *fiber.Ctx) error {
	ctx := &MyCtx{Ctx: c}
	c.Locals("myctx", ctx)
	return c.Next()
}

func (c *MyCtx) Response(data interface{}) error {
	res := map[string]interface{}{
		"msg":  c.Msg,
		"code": c.Code,
	}
	if data != nil {
		res["data"] = data
	}
	return c.JSON(res)
}
func (c *MyCtx) judge(params []interface{}) error {
	if len(params) == 1 {
		paramType := reflect.TypeOf(params[0])
		if paramType.Kind() == reflect.String {
			c.Msg = params[0].(string)
			return c.Response(nil)
		}
		return c.Response(params[0])
	}
	if len(params) == 2 {
		data := params[0]
		msg := params[1].(string)
		if msg != "" {
			c.Msg = msg
		}
		return c.Response(data)
	}

	return c.Response(nil)
}

注册中间件 CtxMiddleware

main.go

func main() {
    // 创建一个Fiber 应用实例
    app := fiber.New()
    // 注册自定义中间件以转换上下文
    app.Use(CtxMiddleware)
    app.Listen('127.0.0.1:8083')  
}

如果是fiber框架直接copy就实现了。其他框架主要是上下文的对象不同。我这边只是提供思路参考。

使用

func test1(c *fiber.Ctx) error {
	// 业务代码
        // 从请求体中读取JSON内容并反序列化
	if err := c.BodyParser(&model); err != nil {
		return c.Status(fiber.StatusBadRequest).SendString("Invalid JSON body")
	}
        // model就是对象数据
	return AppResult(c).Success(model,"操作成功")

}

func test1(c *fiber.Ctx) error {
	// 业务代码
	return AppResult(c).Success()

}

func test1(c *fiber.Ctx) error {
	// 业务代码
	return AppResult(c).Success(model)

}

func test1(c *fiber.Ctx) error {
	// 业务代码
	return AppResult(c).Success("操作成功")

}

支持4种配置非常简单优雅。如果有更优雅的方式请告诉我。这个go实在是想封装个东西太困难了。

go不支持类名调用方法,反射鸡肋

方法重载也不支持,没法写方法名相同,不同参数列表

而且还没办法设置默认参数名,导致还要手动传一个值进来。

可选参数也没办法设置。最后真的想了好久。最终是上面的效果,迫不及待分享给,如果觉得不错的话。能点个赞吗。。