【问题标题】:Access request context anywhere随时随地访问请求上下文
【发布时间】:2016-04-06 00:40:57
【问题描述】:

我正在使用 Express,每次使用日志调试和跟踪我的应用程序时,我都需要访问请求中的一些数据(标头、cookie 等)。

对于其他语言(即:Java),我有“线程上下文”,我可以在其中放置数据,因此每当我记录某些内容时都可以访问它。但据我所知,NodeJS 没有这样的事情,因为我们只有一个线程。

我试图避免在每个函数中传递 req 变量,以便我可以记录该信息。

是否有节点或 expressjs 功能可以让我在任何地方获取数据?

【问题讨论】:

  • 有模块——但老实说隐式请求全局变量很糟糕,你应该尽可能地避免它们。只有您的路由处理程序本身应该访问请求,然后只将相关位传递给需要它们的部分。
  • @Amit 这是一个合法的问题 - 我想可以通过删除“是否有模块”的部分并将其保留为“是否有快速或节点功能”来编辑它以使其更合法"
  • @BenjaminGruenbaum 我明白你的意思,但是为我的所有函数添加一个额外的参数以访问仅与日志记录相关的数据也是不好的
  • @Neuquino 你是对的,你应该将日志功能注入到负责日志记录的组件中——然后将记录器传递给使用它的函数。如果您不想将它传递给所有对象 - 将它们放在类中并将其传递给类的构造函数。这种模式(依赖注入)在现代软件设计中是通用的——您可以使用注入器自动但明确地传递记录器。不受控制的全局状态是可怕的:)
  • @BenjaminGruenbaum Java 和 C# 中的线程局部变量不是“不受控制的全局状态”。它们对于每个线程都是本地的,当涉及到与特定调用链相关的收集状态时,只要程序逻辑由调用函数的函数组成,我看不出如何用依赖注入替换它们?在某些用例中需要它们,并且存在像 Continuation Local Storage 这样的库是有原因的。

标签: node.js express


【解决方案1】:

看看 Continuation Local Storage,它为异步调用链实现了类似于线程上下文的东西:https://github.com/othiym23/node-continuation-local-storage

还有一些努力将异步本地存储构建为 javascript 本身的标准化功能,但仍处于早期阶段:TC39 Zone Proposal https://docs.google.com/presentation/d/1H3E2ToJ8VHgZS8eS6bRv-vg5OksObj5wv6gyzJJwOK0

【讨论】:

  • 这应该被标记为正确答案。当前标记的正确答案未正确回答问题。
  • 请小心这个库,因为我认为它有问题。我在制作多租户应用程序解决方案时尝试过它,而当我执行压力测试时,这个库正在失去上下文。我最终在我需要的每个函数中传递了请求上下文。乍一看,它似乎并不酷,但在我看来,明确的比隐含的要好。
【解决方案2】:

JavaScript 是单线程的这一事实并非限制,也不会妨碍使用“线程上下文”作为使用“普遍可访问状态”的一种手段。一旦进行异步调用并且状态不再符合您的预期,问题就会开始。

这就是为什么全局状态被认为是“坏习惯”的原因之一,您应该努力避免它(尤其是在使用 JavaScript 和/或 Node 进行开发时...)。

相反,您应该绕过一个对象,而不是req。您应该以与每个调用链(从请求事件开始并通过所有内部调用开始)相关的 log 实例传递的方式构造对象或调用函数。该log 实例应使用日志记录所需的任何上下文进行初始化,在您的情况下,应使用原始req 的请求详细信息。

【讨论】:

  • 我不认为在我的所有模块中为我的所有函数添加一个额外的参数只是为了记录日志会是一个优雅的解决方案。我知道这不会像var log = require('myLog'); log.debug ('something') 那样简单。但我正在努力实现这样的目标。
  • 当然有方法——最简单的方法是:域、区域、提供绑定上下文的承诺库(如蓝鸟)、纤程等。
  • @Neuquino 这会导致紧密的代码耦合,会使测试更加困难,会阻止您更改日志记录方案(如果您想要更多上下文怎么办,但只是 req?)甚至不会只要同时需要多个上下文(通过异步代码)就可以工作。
  • @BenjaminGruenbaum - (抱歉只是重写了内容,所以它没有乱序,但是......)当每个“事务”(请求......)存在唯一的上下文对象时,您的所有建议都适用,这就是我的回答,但不会像 Neuquino 的评论中所建议的那样与 require('myLog') 一起使用。
  • 传递包含一小组有用变量的请求上下文没有错,例如日志上下文。对此的纯粹主义态度可能会对架构造成破坏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
相关资源
最近更新 更多