showliuzp 2025-09-23 21:21 采纳率: 84.3%
浏览 10
已结题

golang封装中间件函数


func chk_operator_exists(operator_id int64,log_format string)(info models.LuGuildAccountList,err error){
    info,err = dao.OperatorDetail(operator_id)
    if err != nil{
        logx.Error(log_format)

        return
    }

    if info.Id < 1{
        err = response.NewErrCodeMsg(200, "数据不存在")
        return
    }

    return
}

func (o *Operator) OperatorEdit(req *iapi.OperatorEditReq,guild_id int64) (resp interface{},err error){
    info,err := chk_operator_exists(req.OperatorId,fmt.Sprintf("tags:%+v,操作人员角色编辑,mongo数据库异常,req:%+v,err:%+v", o.LogTag,req,err))
  //继续业务处理
}

我想把chk_operator_exists封装为一个中间件函数,先进行检查,不通过返回error,应该怎么做比较好
  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-09-23 21:22
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    在 Go 语言中,中间件函数通常用于在请求处理前进行一些通用逻辑(如权限校验、日志记录、参数校验等)。你目前的 chk_operator_exists 函数已经实现了对操作员是否存在的一种检查逻辑,但目前它是作为一个普通函数被调用的。为了将其封装为“中间件”风格的函数,我们需要让它返回错误,并在业务逻辑中进行判断。


    ✅ 推荐做法:将 chk_operator_exists 改造成中间件风格

    1. 将 chk_operator_exists 改写为一个中间件函数

    关键点: 中间件函数应该返回一个 error,如果校验失败则直接返回 error,否则继续后续流程。

    func CheckOperatorExists(operatorId int64, logFormat string) (err error) {
        info, err := dao.OperatorDetail(operatorId)
        if err != nil {
            logx.Error(logFormat)
            return err
        }
    
        if info.Id < 1 {
            return response.NewErrCodeMsg(200, "数据不存在")
        }
    
        return nil
    }
    

    说明:

    • 返回值改为 err,而不是 info
    • 如果检查失败,直接返回错误,不再返回 info
    • 这样更符合“中间件”的风格——只负责校验,不负责业务逻辑。

    2. 在 OperatorEdit 方法中使用中间件

    func (o *Operator) OperatorEdit(req *iapi.OperatorEditReq, guild_id int64) (resp interface{}, err error) {
        // 使用中间件函数进行检查
        err = CheckOperatorExists(req.OperatorId, fmt.Sprintf("tags:%+v,操作人员角色编辑,mongo数据库异常,req:%+v,err:%+v", o.LogTag, req, err))
        if err != nil {
            return nil, err
        }
    
        // 继续业务处理...
        // ...
        return resp, nil
    }
    

    说明:

    • 调用中间件函数后,如果返回 err 不为 nil,就直接返回错误。
    • 否则继续执行后续逻辑。

    ✅ 总结:如何将 chk_operator_exists 封装为中间件函数

    1. 修改函数签名,使其返回 error 而不是 infoerror
    2. 统一错误处理,在中间件中返回错误,不再返回结构体。
    3. 在业务方法中调用中间件函数,并根据返回的 error 决定是否继续执行。
    4. 保持日志记录逻辑,可以在中间件内部记录日志。

    📌 示例代码(完整版)

    修改后的中间件函数:

    func CheckOperatorExists(operatorId int64, logFormat string) error {
        info, err := dao.OperatorDetail(operatorId)
        if err != nil {
            logx.Error(logFormat)
            return err
        }
    
        if info.Id < 1 {
            return response.NewErrCodeMsg(200, "数据不存在")
        }
    
        return nil
    }
    

    使用中间件函数的业务方法:

    func (o *Operator) OperatorEdit(req *iapi.OperatorEditReq, guild_id int64) (resp interface{}, err error) {
        // 调用中间件函数
        err = CheckOperatorExists(req.OperatorId, fmt.Sprintf("tags:%+v,操作人员角色编辑,mongo数据库异常,req:%+v,err:%+v", o.LogTag, req, err))
        if err != nil {
            return nil, err
        }
    
        // 此处是正常的业务逻辑
        // ...
    
        return resp, nil
    }
    

    ✅ 优点总结

    | 优点 | 说明 | |------|------| | 复用性强 | 中间件可以被多个业务方法调用,避免重复代码 | | 逻辑清晰 | 检查逻辑集中在一个地方,便于维护和调试 | | 错误处理统一 | 所有错误由中间件统一处理,减少冗余的 if err != nil 判断 |


    如果你希望进一步抽象,也可以考虑将中间件设计成函数式编程风格(例如使用闭包),但这需要根据项目结构来决定。目前的实现方式已经足够简洁且易于维护。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 10月5日
  • 已采纳回答 9月27日
  • 创建了问题 9月23日