I would like to intercept a req.params item in an interception layer:
let's say I have an express server application instance:
const app = express();
with an interception layer:
app.use((req, res, next) => {
console.log(req.params.myParam);
next();
})
and many endpoints like this one:
app.get('/anything/:myParam', (req, res) => res.send('hello'))
this logs 'undefined' which is quite natural because when the interception middleware within the "use" is executed, the param name has not been defined yet. But I really need to known in this interception layer the value of myParam parameter with these constraints:
- I known how the parameter is supposed to be named in the intercepted endpoints (myParam)
- I can't know how the url is structured in the intercepted endpoints (can be /anything/:myParam, or /:myParam/anything and so on...)
Does anyone know a solution for that case ?
CodePudding user response:
The comment from @indrajaj26 about using app.param() leads me on a working solution.
Here is the way I'm proceeding:
/** express application */
const app = express();
// Interception layer
app.param('myParam', (req, res, next, myParam) => {
/* Store myParam into something reusable (like locals as suggested by @nullromo for instance).
* I'm using zonejs in my case: creating a forked zone with myParam stored in zone properties.
*/
next();
});
// Consuming intercepted data. Anywhere in the callstack of any endpoint using "myParam" as request parameter:
console.log(Zone.current.getZoneWith('myParam')?.get('myParam'));
Thanks everyone for your ideas!
CodePudding user response:
A simple solution would be to pass the middleware function when defining the route.
Example:
function middleware(req, res, next) {
console.log(req.params.myParam);
next();
}
app.get('/path', middleware, function(req, res) {
...
});
Full example:
const express = require('express');
const app = express();
function middleware(req, res, next) {
console.log(req.params.myParam);
next();
}
app.get('/path', middleware, function(req, res) {
...
});
app.listen(3000, () => console.log('server is online'));
CodePudding user response:
You can store the params on the response.locals
object for use by later middleware.
const express = require('express');
const app = express();
app.get('/:name', (request, response, next) => {
// generate some kind of result
const result = `Hello, ${request.params.name ?? 'world'}!`;
// save the result and the params onto the request.locals object
response.locals = { params: request.params, result };
// call the next middleware to pass on the params and result
next();
});
app.use((request, response, next) => {
// here you have the params since they were parsed by the previous middleware
console.log(`Intercepted: ${JSON.stringify(response.locals.params)}`);
// now actually send the response that you wanted to send
response.status(200).send(response.locals.result);
});
app.listen(3000, () => {
console.log('listening');
});
This requires storing the request.params
on the response.locals
object in every handler, which is not the greatest. But it also means that you don't have to specify the interceptor middleware every time, if that's a problem for your case.