Reputation: 88
I'm new to Express and Typescript in general and I want to understand how middleware's work in the request-response chain. Below, I have a function which starts the express server and configures two middleware's one after the other.
export async function startExpressServer() {
...
app.use(firstMiddleware);
app.use(secondMiddleware);
...
}
I understand that requests flow through this middleware chain. Each middleware does it's own processing and then calls next()
in order to pass execution to the next middleware.
My question is: If I modify/add data to the req
/res
objects in the second middleware, can I have access to those modifications in the first middleware?
export const firstMiddleware: Handler = (req, res, next) => {
// do some processing here
next(); // call next function to go to secondMiddleware
// can I write some logic here to access the modified req/res objects from the secondMiddleware?
}
export const secondMiddleware: Handler = (req, res, next) => {
// add something to the req/res objects
next();
}
Basically, I'm trying to figure out if the request processing chain is one-way or two-way. If the data flows only in one direction, do you know of an alternative that may come handy in my use case?
Thank you!
Upvotes: 1
Views: 887
Reputation: 1182
My question is: If I modify/add data to the req/res objects in the second middleware, can I have access to those modifications in the first middleware?
no, I don't think that is possible, since those modifications are from the second middleware.
but, you can do like this.
export const firstMiddleware: Handler = async (req, res, next) => {
// do some process
await new Promise((resolve) => secondMiddleware(req, res, resolve));
// access modified req, res
next();
}
but, keep in mind that this is probably cause an error. Because the secondMiddleware
could possibly end the connection res.end()
without mark the promise as done (either resolve or reject) since we only have resolve and resolve is not called if the next()
is not called. you should implement better. but the thing is, it is not possible, since the flow is just from first to end.
things will be easier if you split those middleware.
export async function startExpressServer() {
...
app.use(firstMiddleware); // do some process
app.use(secondMiddleware); // modify req and res
app.use(thirdMiddleware); // modified req res is accessible 👍
...
}
Upvotes: 1
Reputation: 88
I'm just going to share my own answer to this, maybe it will be of some help to somebody.
The Express request processing chain constructed through the addition of multiple middlewares one after the other is one way. The request and response objects are the same objects in all the middlewares.
You can continue the execution of the next middleware by using next
or you can stop it by calling res.end()
, res.json()
, res.send()
.
The docs are pretty clear: https://expressjs.com/en/guide/using-middleware.html
For my example, I wanted to be able to have some kind of post processing before the response is set out. To do this, you would have to add that logic in each middleware before the execution flow stops through res.send
for example.
If you have multiple middlewares, you may want to generically tackle this by wrapping the entire express.Application
:
https://gist.github.com/devarajchidambaram/aa08ae7116d426e5b8ba5997e4629149
Upvotes: 0