在上下文中存储请求和会话 ID。上下文被认为是坏的吗?

Kon*_*che 6 middleware response go websocket

Jack Lindamood 发表了一篇出色的博客文章《如何在 Go 1.7 中正确使用 context.Context》,可归结为以下报价:

Context.Value 应该提供信息,而不是控制。如果您正确使用 context.Value,这是我认为应该指导的主要原则。context.Value 的内容适用于维护者而不是用户。决不应该要求输入记录或预期结果。

目前,我正在使用Context以下信息传输:

  • RequestID它在客户端生成并传递到 Go 后端,并且仅通过命令链,然后再次插入响应中。如果没有RequestID响应,客户端就会崩溃。

  • SessionID标识 WebSocket 会话,当在异步计算(例如工作队列)中生成某些响应时,这一点很重要,以便标识应在哪个 WebSocket 会话上发送响应。

当非常认真地对待这个定义时,我会说两者都违反了意图,context.Context但话又说回来,它们的值在发出整个请求时不会改变任何行为,它仅在生成响应时相关。

还有什么选择呢?在服务器 API 中拥有context.Contextfor 元数据实际上有助于维护精益方法签名,因为这些数据实际上与 API 无关,但仅对传输层很重要,这就是为什么我不愿意创建类似请求结构的内容:

type Request struct {
    RequestID string
    SessionID string
}
Run Code Online (Sandbox Code Playgroud)

并使其成为每个 API 方法的一部分,该方法仅在发送响应之前传递。  

Pur*_*ran 0

根据我的理解,上下文应该仅限于传递请求或会话 ID 等内容。在我的应用程序中,我在我的中间件之一中执行如下操作。有助于可观察性

if next != nil {
   if requestID != "" {
     b := context.WithValue(r.Context(), "requestId", requestID)
     r = r.WithContext(b)
   }
   next.ServeHTTP(w, r)
}
Run Code Online (Sandbox Code Playgroud)