最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I properly share context using express and typescript - Stack Overflow

programmeradmin0浏览0评论

I'd like to expose a value to all request handlers using express & typescript. I'd like to be able to "inject" this value from a middleware (or some other way), the point is that it should be easy to mock it in case I need to.

I came up with this solution:

// 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)

My questions:

  • Is this the intended way of doing this using express? I scouted the API but couldn't find a better solution
  • The extra data is attached to the request. Is there any other way that does this without mutating the request or response itself?
  • The type Request & HasContext has to be defined in each request that uses this context. Is there a better way?

I'd like to expose a value to all request handlers using express & typescript. I'd like to be able to "inject" this value from a middleware (or some other way), the point is that it should be easy to mock it in case I need to.

I came up with this solution:

// 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)

My questions:

  • Is this the intended way of doing this using express? I scouted the API but couldn't find a better solution
  • The extra data is attached to the request. Is there any other way that does this without mutating the request or response itself?
  • The type Request & HasContext has to be defined in each request that uses this context. Is there a better way?
Share Improve this question edited Oct 11, 2021 at 17:50 Aluan Haddad 31.9k10 gold badges83 silver badges95 bronze badges asked Oct 11, 2021 at 17:35 Balázs ÉdesBalázs Édes 13.8k7 gold badges60 silver badges104 bronze badges 3
  • You can define a custom type for Request & HasContext somewhere and import it – Phix Commented Oct 11, 2021 at 17:38
  • @Phix I know, not really the point of the question. Still for each request handler I have to use the custom type. – Balázs Édes Commented Oct 11, 2021 at 17:42
  • See this question and the answer stackoverflow./q/58787934/1915893. It shows how you can augment the types in the express package based – Aluan Haddad Commented Oct 11, 2021 at 17:55
Add a ment  | 

1 Answer 1

Reset to default 7

You can overwrite the express Request interface to include your context property. This way you don't have to specify the type anywhere. It will also keep all the other properties that Request normally has.

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

I would remend not using the Request object to store information. Express remends the use of the res.locals property.

发布评论

评论列表(0)

  1. 暂无评论