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?