go函数的匿名调用,inject/Invoke,protobuf方法的调用

一、由于以前的代码是通过pb来传输数据的,大体流程是:前端—>后端的接口–>后端再请求pb服务接口。示例代码如下:
1.接收前端参数

// @Summary LTV趋势
// @Description LTV趋势
// @Tags 投放数据/LTV数据
// @Accept  application/json
// @Product application/json
// @Param data body dass.GetLtvDataListRequest true "body"
// @Success 200 {string} string	"{"code": 200, "message": "success"}"
// @Router /api/v1/custom/finance/financedata/ltv/list [post]
// @Security Bearer
func GetLtvDataList(c *gin.Context) {
	request := &pb.GetLtvDataListRequest{}
	err := c.ShouldBindBodyWith(&request, binding.JSON)
	err = c.ShouldBindBodyWith(&request.Request, binding.JSON)
	tools.HasError(err, "", -1)
	global.Logger.Debug(request)
	if len(request.GetRequest().Games) == 0 {
		err = errors.New("游戏不能为空")
		tools.HasError(err, "", -1)
	}
	err = common.CheckGamesPerm(c, &request.GetRequest().Games)
	tools.HasError(err, "", -1)
	err = common.CheckPlatformsPerm(c, &request.GetRequest().Platforms)
	tools.HasError(err, "", -1)
	if request.GetRequest().AdChannelId == "" {
		err = common.CheckAdChannelIdsPerm(c, &request.GetRequest().AdChannelIds)
		tools.HasError(err, "", -1)
	}
	response, err := dass.GetLtvDataList(request)
	tools.HasError(err, "", -1)
	app.OK(c, response.List, "success")
}

2.请求 dass.GetLtvDataList()

// 获取LTV数据列表
func GetLtvDataList(request *pb.GetLtvDataListRequest) (response *pb.GetLtvDataListResponse, err error) {
	response = rpc.GetLtvDataListRequest(request)
	if response == nil {
		err = errorDassService
		return
	}
	if response.Code != StatusOk {
		return nil, errors.New(response.Msg)
	}
	return
}

3.请求pb方法 rpc.GetLtvDataListRequest()

//获取LTV数据列表
func GetLtvDataListRequest(request *pb.GetLtvDataListRequest) *pb.GetLtvDataListResponse {
	rpcClient := pb.NewFinanceDataApiClient(xrpc.DassConn())
	ctx, cancel := context.WithTimeout(context.Background(), DassRpcTimeout)
	defer cancel()
	response, err := rpcClient.GetLtvDataList(ctx, request)
	if err != nil {
		global.Logger.Warning("func=grpcSvc_GetLtvDataListRequest&err=%s", err.Error())
		return nil
	}
	return response
}

问题:每个后台走pb的接口都要新建一个2和3的方法,里面的逻辑都是一样的 就造成了代码的的冗余。
改善:前端请求到后端接口之后,我只需要请求一个固定的方法,传对应的参数就可以了 而不需要重复的去写2和3的方法。
具体思路:
(1).把pb的方法列表注册到map里面
(2)请求过来之后把方法的名称,和参数传到CallLogMeth()方法里面
(3)CallLogMeth方法去请求对应的pb方法
用到了,go语言的反射和依赖注入。最开始是打算使用inject/Invoke这个第三方包来实现,但是在调用invoke这个方法的时候会报参数不全最开始的代码如下:

const (
	FunctionNotFund                                    = "方法未找到!"
	OperationsAppGiftApiClientAddGift                  = "OperationsAppGiftApiClient.AddGift"
	OperationsAppGiftApiClientDeleteGift               = "OperationsAppGiftApiClient.DeleteGift"
	OperationsAppGiftApiClientGetGiftById              = "OperationsAppGiftApiClient.GetGiftById"
	OperationsAppGiftApiClientGetGiftList              = "OperationsAppGiftApiClient.GetGiftList"
	OperationsAppGiftApiClientUpdateGift               = "OperationsAppGiftApiClient.UpdateGift"
	OperationsAppGiftRecordApiClientGetGiftRecordList  = "OperationsAppGiftRecordApiClient.GetGiftRecordList"
	OperationsAppGeneralApiClientGetAppGeneralConfInfo = "OperationsAppGeneralApiClient.GetAppGeneralConfInfo"
	OperationsAppGeneralApiClientUpdateAppGeneralConf  = "OperationsAppGeneralApiClient.UpdateAppGeneralConf"
)

var RPCFuns *RpcFunc

type CodeResponse interface {
	GetCode() int32
	GetMsg() string
}

func init() {
	RPCFuns = new(RpcFunc)
	RPCFuns.FunsInit()
}

type RpcFunc struct {
	RpcFuncList map[string]interface{}
}

func (c *RpcFunc) CallLogMeth(methodName string, params interface{}) (response interface{}, err error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	inj := inject.New()
	inj.Map(ctx)
	inj.Map(&params)
	if fn, ok := c.RpcFuncList[methodName]; ok {
		response, err = inj.Invoke(fn)
		if err != nil {
			global.Logger.Warning("func=grpcSvc_welfare_%s&err=%s", methodName, err.Error())
			return
		}
		if res, ok := response.(CodeResponse); ok {
			if res.GetCode() != StatusOk {
				return nil, errors.New(res.GetMsg())
			}
		}
	} else {
		err = errors.New(FunctionNotFund)
	}
	return
}

func (c *RpcFunc) FunsInit() {
	AppGiftApiClient := pb.NewAppGiftApiClient(xrpc.Welfare())
	RPCFuns.RpcFuncList = map[string]interface{}{}
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientAddGift] = AppGiftApiClient.AddGift
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientDeleteGift] = AppGiftApiClient.DeleteGift
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientGetGiftById] = AppGiftApiClient.GetGiftById
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientGetGiftList] = AppGiftApiClient.GetGiftList
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientUpdateGift] = AppGiftApiClient.UpdateGift
	AppGiftRecordApiClient := pb.NewAppGiftRecordApiClient(xrpc.Welfare())
	RPCFuns.RpcFuncList[OperationsAppGiftRecordApiClientGetGiftRecordList] = AppGiftRecordApiClient.GetGiftRecordList
	AppGeneralApiClient := pb.NewAppGeneralApiClient(xrpc.Welfare())
	RPCFuns.RpcFuncList[OperationsAppGeneralApiClientGetAppGeneralConfInfo] = AppGeneralApiClient.GetAppGeneralConfInfo
	RPCFuns.RpcFuncList[OperationsAppGeneralApiClientUpdateAppGeneralConf] = AppGeneralApiClient.UpdateAppGeneralConf
}

最后我在map里面存方法,然后参数过来之后我用断言这个参数的类型的方式来完成调用。最后代码及流程如下
1.接收前端的请求

// @Summary 详情
// @Description 详情
// @Tags 运营中心/新游社/礼包管理
// @Accept  application/json
// @Product application/json
// @Param data body  welfare.WelfareIdRequest false "param"
// @Success 200 {object} welfare.GetGiftByIdResponse
// @Router /api/v1/custom/operatecenter/xys/package/info [get]
// @Security Bearer
func GetPackageInfo(c *gin.Context) {
	id, _ := tools.StringToInt(c.Query("id"))
	request := &pb.WelfareIdRequest{
		Id: uint32(id),
	}
	global.Logger.Debug(request)
	response, err := xrpc.RPCFuns.CallLogMeth(xrpc.OperationsAppGiftApiClientGetGiftById, request)
	tools.HasError(err, "", -1)
	app.OK(c, response, "success")
}

2.请求pb的接口

const StatusOk = 1000
const (
	FunctionNotFund                                    = "方法未找到!"
	OperationsAppGiftApiClientAddGift                  = "OperationsAppGiftApiClient.AddGift"
	OperationsAppGiftApiClientDeleteGift               = "OperationsAppGiftApiClient.DeleteGift"
	OperationsAppGiftApiClientGetGiftById              = "OperationsAppGiftApiClient.GetGiftById"
	OperationsAppGiftApiClientGetGiftList              = "OperationsAppGiftApiClient.GetGiftList"
	OperationsAppGiftApiClientUpdateGift               = "OperationsAppGiftApiClient.UpdateGift"
	OperationsAppGiftRecordApiClientGetGiftRecordList  = "OperationsAppGiftRecordApiClient.GetGiftRecordList"
	OperationsAppGeneralApiClientGetAppGeneralConfInfo = "OperationsAppGeneralApiClient.GetAppGeneralConfInfo"
	OperationsAppGeneralApiClientUpdateAppGeneralConf  = "OperationsAppGeneralApiClient.UpdateAppGeneralConf"
)

var RPCFuns *RpcFunc

type CodeResponse interface {
	GetCode() int32
	GetMsg() string
}

func init() {
	RPCFuns = new(RpcFunc)
}

type RpcFunc struct {
	RpcFuncList map[string]GrpcFunc
}

type GrpcFunc = func(ctx context.Context, request interface{}) (interface{}, error)

func (c *RpcFunc) CallLogMeth(methodName string, params interface{}) (response interface{}, err error) {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	if fn, ok := c.RpcFuncList[methodName]; ok {
		response, err = fn(ctx, params)
		if err != nil {
			global.Logger.Warning("func=grpcSvc_%s&err=%s", methodName, err.Error())
			return
		}
		global.Logger.Debug(response)
		if res, ok := response.(CodeResponse); ok {
			if res.GetCode() != StatusOk {
				return nil, errors.New(res.GetMsg())
			}
		}
	} else {
		err = errors.New(FunctionNotFund)
	}
	return
}

func (c *RpcFunc) FunsInit() {
	AppGiftApiClient := welfarePb.NewAppGiftApiClient(Welfare())
	RPCFuns.RpcFuncList = map[string]GrpcFunc{}
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientAddGift] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGiftApiClient.AddGift(ctx, request.(*welfarePb.AddGiftRequest))
	}
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientDeleteGift] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGiftApiClient.DeleteGift(ctx, request.(*welfarePb.WelfareIdRequest))
	}
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientGetGiftById] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGiftApiClient.GetGiftById(ctx, request.(*welfarePb.WelfareIdRequest))
	}
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientGetGiftList] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGiftApiClient.GetGiftList(ctx, request.(*welfarePb.GiftListRequest))
	}
	RPCFuns.RpcFuncList[OperationsAppGiftApiClientUpdateGift] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGiftApiClient.UpdateGift(ctx, request.(*welfarePb.UpdateGiftRequest))
	}
	AppGiftRecordApiClient := welfarePb.NewAppGiftRecordApiClient(Welfare())
	RPCFuns.RpcFuncList[OperationsAppGiftRecordApiClientGetGiftRecordList] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGiftRecordApiClient.GetGiftRecordList(ctx, request.(*welfarePb.GiftRecordListRequest))
	}
	AppGeneralApiClient := welfarePb.NewAppGeneralApiClient(Welfare())
	RPCFuns.RpcFuncList[OperationsAppGeneralApiClientGetAppGeneralConfInfo] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGeneralApiClient.GetAppGeneralConfInfo(ctx, request.(*welfarePb.WelfareNullRequest))
	}
	RPCFuns.RpcFuncList[OperationsAppGeneralApiClientUpdateAppGeneralConf] = func(ctx context.Context, request interface{}) (interface{}, error) {
		return AppGeneralApiClient.UpdateAppGeneralConf(ctx, request.(*welfarePb.AppGeneralApiInfo))
	}
}

二、这种方法感觉还不够简洁,还想在优化优化,请各位大佬指教

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值