【问题标题】:How do I properly share context using express and typescript如何使用 express 和 typescript 正确共享上下文
【发布时间】:2021-11-30 10:47:19
【问题描述】:

我想使用 express & typescript 向所有请求处理程序公开一个值。我希望能够从中间件(或其他方式)“注入”这个值,关键是如果我需要它应该很容易模拟它。

我想出了这个解决方案:

// The context type, I'd like to be able to inject this using the middleware below. 
// In a real scenario think of this like a database connection, etc.
type RequestContext = {
  foo: string
}

// The type enriching the Request type with the context field
type HasContext = {
  context: RequestContext
}

// Middleware attaching the context to the request
const contextMiddleware =
  (context: RequestContext) => 
  (req: Request & Partial<HasContext>, _res: Response, next: NextFunction) => {
    req.context = context
    next()
  }


// Now an actual route using the extra type
const mainRoute = express.Router().get('/test', (req: Request & HasContext, res) => {
  res.json({ context: req.context })
})

// Adding the middlewares and listen
app.use(contextMiddleware({ foo: 'bar' }))
app.use(mainRoute)

app.listen(8000)

我的问题:

  • 这是使用 express 的预期方式吗?我探索了 API,但找不到更好的解决方案
  • 额外的数据附加到请求中。有没有其他方法可以在不改变请求或响应本身的情况下做到这一点?
  • Request &amp; HasContext 类型必须在使用此上下文的每个请求中定义。有没有更好的方法?

【问题讨论】:

  • 您可以在某处为Request &amp; HasContext 定义一个自定义类型并导入它
  • @Phix 我知道,这不是问题的重点。对于每个请求处理程序,我仍然必须使用自定义类型。
  • 查看这个问题和答案stackoverflow.com/q/58787934/1915893。它展示了如何增加基于 express 包中的类型

标签: javascript node.js typescript express dependency-injection


【解决方案1】:

您可以覆盖 express Request 接口以包含您的 context 属性。这样您就不必在任何地方指定类型。它还将保留Request 通常拥有的所有其他属性。

declare global {
  namespace Express {
    interface Request {
      context: RequestContext 
    }
  }
}

我建议不要使用Request 对象来存储信息。 Express 建议使用res.locals 属性。

【讨论】:

  • 太棒了,谢谢,这就是我要找的东西,response.locals 就是这样。
猜你喜欢
  • 1970-01-01
  • 2015-05-29
  • 2014-01-09
  • 1970-01-01
  • 2013-12-11
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
相关资源
最近更新 更多