-
-
Notifications
You must be signed in to change notification settings - Fork 17.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add originalRoute like originalUrl #2501
Comments
Can you show a little express app that makes use of this as well, please :)? |
@dougwilson Is the following good enough? A request could be
|
How would it work for RegExp routes or array routes? |
i.e. we need it to work if your main file has app.use(['/api', '/api/v1'], require('./api').router); or app.use(/^\/api(?:\/v1)?\//i, require('./api').router); |
@dougwilson I see your concerns, and that we have to re-think it, to ensure all methods will be handled correctly. Another approach could be to simply expose an array of routes in the order they were matched, and if you are going to use the data, you'll have to deal with the different data types. Assume that you'd replaced my route in I don't know if newrelic is able to handle all cases (haven't investigated their code further), but they do something similar to my hacky workaround. https://github.com/newrelic/node-newrelic/blob/master/lib/instrumentation/express.js#L184 |
That's fine. I don't mind adding something for this. We just want to make sure that what gets added to Express core is compatible with all of Express's features, rather than only the features a particular user just happens to be using it is all :) |
I'm all in on that - I did not just want this to be a feature for me :) This issue was to rise a discussion on a good way to implement something like this, as the new Router in Express 4 is giving the power to split and nest routes, but the downside is, that it can be hard to know exactly where you are, and for logging purpose it is often useful to be able to group by route rather than exact URL, to know how many request of a specific type has happend. Which way do you prefer? Some way to concat the routes or should we go with the array of routes a particular request has travelled from entry to the final route? |
An array that gets built up sounds like the simplest method to me. |
An array is fine with me... if a use case needs another format, it simply has to handle the transformation from the array to something else, eg a concat-string. |
Hey, I can confirm that it would be great to have originalRoute. I'm trying to implement declarative ACL based on routing so it's very uncomfortable to deal with it without knowing what route was matched =( |
Any traction on a PR? |
@dougwilson Created a PR about this (#2864). |
@ajfranzoia Thank you very much |
@dougwilson @ajfranzoia @danieljuhl @devlato thoughts on #3100? |
Hi @evanshortiss it looks like that PR doesn't address the concerns brought up in this PR. |
@ajfranzoia @danieljuhl @devlato, your input would be appreciated based on @dougwilson's latest comments on #3100. Currently #3100 is building up an Array of all matched routes as discussed in this PR. @dougwilson rightly suggested that req.route could be used for some scenarios. req.route is workable so long as you only need the relative path. An issue arises when you'd like to have access to all matched routes. The code below for example cannot provide the full matched path, only the local path, thus we lose "/hey" in logs, analytics, and wherever else your use case requires. var app = require('express')();
var route = require('express').Router();
route.get('/you/:id', function (req, res) {
res.end(req.route.path); // Will return "/you/:id", not "/hey/you/:id" or similar
});
app.use('/hey', route);
app.listen(3000); There are ways around this using middleware or alternative structures, but think it would be nice if express had the ability to provide this information in a clean, clear built-in manner. My thoughts on a middleware is something to the effect of this, which I'd actually settle for if adding this behaviour to express doesn't make sense: function expressMatchedMiddleware (req, res, next) {
if (!req.matchedRoutes) {
req.matchedRoutes = [];
}
if (req.route) {
req.matchedRoutes.push(req.route);
}
next();
}; |
WRT #3100 as well. Since the Let's look at some scenarios.
My suggestion would be to let the users implement their own ways of retrieving the absolute path of the matched route(s), for use cases unique to their own requirements. |
@hacksparrow your scenarios are valid, but it seems like you assume that the API should return a combined string. Or am I getting you wrong? I believe it has already been discussed a lot, that the only solution that would make sense, is to return an array of the actual route definitions, that be a string, regex, an array or whatever is allowed by express. As I see it, @evanshortiss has actually handled that, though more test scenarios should be created, to ensure the API is handling all kinds of route definitions. |
@danieljuhl I am not making any assumptions about what the API should return. In fact, I cannot think of anything that should be returned, which would make sense universally. Scenarios 1 and 3 highlight the issue of using an array as implemented by @evanshortiss. |
@hacksparrow here are some thoughts.
Ultimately the goal of this issue is to enable a developer to programatically determine matched routes which seems like a reasonable request. But I agree, we can see it's a challenge to achieve in a manner that works "universally" and raises the question of can and/or should express attempt provide this. |
@evanshortiss yes, I agree it is a reasonable request. It's just that the API is not very convincing or a lot of complexities will be involved (eg: detecting passthroughs). It would be great to have a really elegant solution. 👍 for "This information can be useful at runtime for logging", hadn't thought about it. |
@hacksparrow I think the purpose of this PR is to get the routes matched not the 'route handlers' matched. The purpose of this PR, IMHO, is to get the 'context', and not just the final route matched. I do aknowledge that it can look messy if you have a very complex route structure, but I can't see how you can make something messy, look elegant - at least not for now :) |
Hi @danieljuhl which PR are you referring to? This is just an issue and references a few PRs, so just trying to get context on your statement. |
@dougwilson - sorry, PR #3100 as referenced by @hacksparrow |
Gotcha. I was thinking that, @danieljuhl , but all the examples in the #3100 seem to indicate the intention of the PR is to build the final route matched, which seems to conflict what your description of your PR. Perhaps I'm just misunderstanding here? |
@dougwilson @danieljuhl correct, it's to get context. For me personally I'd like to construct a string that represents the matched URL. @hacksparrow has a nice solution here that would allow one to do what my PR does, without technically adding it as a feature to express. |
any solution for this will make me happy ;) |
Another use case would be when supporting Prometheus metrics for all endpoints. To do that, one could use middleware functions at the app-level and use the app.use((req, res, next) => {
requestsCount.inc({api: req.originalRoute, method: req.method});
}); Since app.use((req, res, next) => {
requestsCount.inc({api: normalize(req.url), method: req.method});
}); .. where |
The router has been moved, and this would be a feature of the router. You can see what IMO is the best option for this on the Any future conversation should be had over on that thread, as it is where we would make this kind of change. |
So it's impossible to have metrics for "response times by endpoint" using express with the current implementation of router? |
In a request we can get the originalUrl, which is the complete URL for the request after it has travelled through nested routes.
But I think an originalRoute would be at least as usefull, especially for request logging.
I don't think it should be that difficult to add.
Currently I've made a simple hack to accomplish this, but I rather see it built-in.
The text was updated successfully, but these errors were encountered: