Session 从web服务API在context.context中添加多个键值

Session 从web服务API在context.context中添加多个键值,session,go,method-signature,Session,Go,Method Signature,我有一个用Go编写的web应用程序,其中包含多个模块,一个处理所有与数据库相关的事情,一个处理报告,一个包含所有web服务,一个只用于业务逻辑和数据完整性验证,还有其他几个模块。所以,我有很多方法,这些模块已经涵盖了很多功能 现在,我们需要在web服务中使用会话,也需要在某些API中使用事务。我想到的第一种方法是更改现有方法的签名,以支持会话、事务(*sql.Tx)(这是一项痛苦的任务,但无论如何都要做!)。现在,我担心,如果将来有什么东西需要通过所有这些方法来传递,那么我应该再次通过这个循环来

我有一个用Go编写的web应用程序,其中包含多个模块,一个处理所有与数据库相关的事情,一个处理报告,一个包含所有web服务,一个只用于业务逻辑和数据完整性验证,还有其他几个模块。所以,我有很多方法,这些模块已经涵盖了很多功能

现在,我们需要在web服务中使用会话,也需要在某些API中使用事务。我想到的第一种方法是更改现有方法的签名,以支持会话、事务(*sql.Tx)(这是一项痛苦的任务,但无论如何都要做!)。现在,我担心,如果将来有什么东西需要通过所有这些方法来传递,那么我应该再次通过这个循环来再次更改方法签名吗?这似乎不是一个好办法

后来,我发现context.context可能是一种很好的方法(当然,除此之外,您还可以建议其他方法!),对于每个方法调用,只需在方法调用的第一个参数处传递context参数,因此我只需更改方法签名一次。如果我采用这种方法,谁能告诉我如何在该上下文对象中设置/传递多个键(session,sql.Tx)? (AFAIK,context.context提供了
WithValue
方法,但是我可以将它用于多个键吗?我如何在嵌套函数调用中设置键,这可能吗?)

其实,这个问题有两个问题:

我应该考虑我的解决方案<代码>上下文>上下文< /代码>吗?如果没有,请告诉我另一种方法
  • 如何在
    context.context
    中设置多个键和值

  • 最后,我在研究了上一篇文章之后,决定使用上下文包解决方案。尤其是我发现这很有帮助

    嗯,我可以为上下文定制解决方案(啊,有点!)。但由于Go已经有了解决方案,我将使用上下文包

    现在,我只需要在每个方法中使用会话和数据库事务来支持启动时的事务和用户身份验证、授权


    在应用程序的每个方法中都有
    context.context
    可能会造成开销,因为目前我不需要取消、截止日期和超时功能,但将来可能会有所帮助。

    对于第二个问题,您可以在struct中对所有键/值进行分组,如下所示:

    type vars struct {
        lock    sync.Mutex
        db      *sql.DB
    }
    
    然后可以在上下文中添加此结构:

    ctx := context.WithValue(context.Background(), "values", vars{lock: mylock, db: mydb})
    
    您可以检索它:

    ctxVars, ok := r.Context().Value("values").(vars)
    if !ok {
        log.Println(err)
        return err
    }
    db := ctxVars.db
    lock := ctxVars.lock
    

    我希望它能帮助您。

    您可以通过设置多个值来设置多个值。你能展示一下你在做这件事时遇到的问题吗?您也可以只设置一个值,该值包含一个结构中的所有数据。同样,我在上下文方面没有深入的经验,正如我所看到的,程序员使用值返回上下文,如
    ip
    userkey
    。问题是,如果我想在上下文中使用sql.Tx以及会话对象,我将如何实现这一点,以便嵌套函数可以从上下文中提取和使用该信息?请参阅相关问题;还有可能重复。谢谢@icza分享链接。我建议在使用值上下文时要小心。有许多潜在的问题,其中最重要的是类型安全性的损失和透明度的损失:通过接受上下文参数,函数或方法不会公开关于其实际需求的任何信息。我认为,有很多关于背景问题的帖子。