从Web Services API中添加多个键值.Context



我有一个用多个模块编写的Web应用程序,一个与所有数据库相关的事物,一个处理报告,一个人组成了所有Web服务,一个仅用于业务逻辑和数据完整性验证和其他几个。因此,我有许多方法,这些模块已涵盖了功能。

现在,要求是在Web服务中使用会话,以及我们需要在某些API中使用交易。我想到的第一种方法是更改支持会话的现有方法的签名,交易(*sql.tx)(这是一项痛苦的任务,但无论如何都必须做!)。现在,恐怕将来会发生一些需要通过所有这些方法,然后我是否应该再次经过此周期才能再次更改方法签名,该怎么办?这似乎不是一个好方法。

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

实际上,这个问题有两个问题:

  1. 我应该考虑解决方案的context.Context吗?如果没有,请给我另一种方法。
  2. 如何在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

我希望它对您有帮助。

最后,在研究了GO上下文体验报告中的文章之后,我决定使用上下文包解决方案。尤其是我发现戴夫·切尼(Dave Cheney)的文章很有帮助。

好吧,我可以作为大猩猩(啊,有点!)作为上下文的自定义解决方案。但是由于GO已经有一个解决方案,所以我会选择上下文包。

现在,我只需要每种方法中的会话和数据库事务即可在开始时支持交易,并且用户身份验证,授权。

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

最新更新