Home > other >  How do I properly share context using express and typescript
How do I properly share context using express and typescript

Time:10-12

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?

CodePudding user response:

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 recommend not using the Request object to store information. Express recommends the use of the res.locals property.

  • Related