express
express copied to clipboard
Allow for multiple parameter names in router.param()
Hi,
I just found out about router.param() and immediately started using it in my code. It makes checks based on parameters so darn clean :) Really good job on the inventor of that idea!
While using it i found myself wondering with a url like: "/:year/:month/:day". How can you make a router.param(...) function that is called when exactly those 3 arguments have been provided in the url? Perhaps it is possible, but i haven't seen a way in the documentation.
Since router.param() works on parameter names, i would suggest a feature like the following to allow for an implementation of the above to be possible in router.param().
router.param(['year', 'month', 'day'], (req, res, next, obj) => {
obj.year; // contain the year value
obj.month; // contain the month value
obj.day; // contain the day value
});
I would say that the first array in which the params are provided as string must be the exact order in which they would occur in the app.get('/:year/:month/:day' ...) function;
Is there any technical (or practical) reason why a feature like this wouldn't be possible? What are your thoughts on this?
Best regards, Mark
He @markg85 Can i have some other Details LIke your Total api structure so that I can work with my local Express.js Server
He @markg85 Can i have some other Details LIke your Total api structure so that I can work with my local Express.js Server
What do you mean? I have no further details? The topic i started is a feature request :) I don't have an implementation for that request.
Having briefly looked into the source code of router.param()
(which is proto.param()
in router/index.js
), I noticed that all current router.param()
did is push the callback on the router.params[paramName]
array, and does nothing else. router.handle()
, a not documented method, does the actual work. It calls another internal method router.process_params()
, that actually invokes the pushed callbacks on each parameter one by one, sequentially without repeat. From index.js
:
proto.process_params = function process_params(layer, called, req, res, done) {
var params = this.params;
//...
function param() {
//...
key = keys[i++];
name = key.name;
//...
paramCallbacks = params[name];
//...
paramCallback();
}
function paramCallback(err) {
var fn = paramCallbacks[paramIndex++];
//...
if (!fn) return param();
try {
fn(req, res, paramCallback, paramVal, key.name);
} catch (e) {
paramCallback(e);
}
}
param();
}
I believe to add the feature you asked may require changing these structures, and I don't feel of that much necessity if you can just give the job to a normal app.use()
like methods.
@kevinkassimo Thank you for your response! Could you provide an example for the app.use() version of a "/:year/:month/:day" structure? I don't see how to do that, but that is likely due to just not knowing about it :)
@markg85 req.params
will serve as the obj
you wanted in normal path matching methods. Thus I believe something like
app.get("/:year/:month/:day", function (req, res, next) {
req.params["year"];
req.params.month;
req.params.day
//...
next();
})
should be good enough. (I should have said app.METHOD()
, as app.use()
is more likely for middleware and does prefix matching.)
It would be good to have the router.param()
accepting multiple middlewares, that will permit us to split our middleware
example:
router.param('userId',
(req: Request, res: Response, next: NextFunction) => {
// Common middleware validating the data
},
(req: Request, res: Response, next: NextFunction) => {
// Middleware to assign the data, etc...
}
)