-
-
Notifications
You must be signed in to change notification settings - Fork 103
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
Store matched routes in request #34
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There hasn't been much discussion on this since the original thread, but I just wanted to mention that I would really like to see this feature land for the router before [email protected]
.
@@ -286,6 +286,11 @@ Router.prototype.handle = function handle(req, res, callback) { | |||
return next(layerError || err) | |||
} | |||
|
|||
// store matched routes | |||
if (layer.path) { | |||
req.matchedRoutes = (req.matchedRoutes || []).concat(layer.matchedPath.path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to create unnecessary arrays. Can you instead only create a new array the first time, then push to it after?
req. matchedRoutes = req.matchedRoutes || []
req.matchedRoutes.push(layer.matchedPath.path)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (path === '/' && opts.end === false) { | ||
this.regexp.fast_slash = true | ||
if (paths === '/' && opts.end === false) { | ||
this.fastSlash = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
V8 can do optimizations if the shape of an object remains the same. This addition will have only some Layer
's with a fastSlash
property. To optimize this, you should define it as undefined
above, or false
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
|
||
debug('new %s', path) | ||
debug('new %s', paths) | ||
var opts = options || {} | ||
|
||
this.handle = fn | ||
this.name = fn.name || '<anonymous>' | ||
this.params = undefined | ||
this.path = undefined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a line for this.matchedPath = undefined
, see comment below for reasoning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return true | ||
} | ||
|
||
var m = this.regexp.exec(path) | ||
var checkPath, m; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the express modules are working toward compliance with standard
. Which includes the rule that variable declarations are each on a single line. We have doing it piecemeal because it would cause too many conflicts otherwise, so since this is a new line, can you make the change just here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -985,6 +985,31 @@ describe('Router', function () { | |||
}) | |||
}) | |||
|
|||
describe('req.matchedRoutes', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as comment above, can you make the formatting through here function () {
? As per standard
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, maybe we should change the property name to |
- set `__mountpath` in `.use()` - override `process_params` to add `req.matchedRoutes` `req.matchedRoutes` is a proposed addition to express v5: pillarjs/router#34 Doing this because in goodeggs-stats, we need to know what route we are currently on when we are publishing metrics to librato. In express v4 there is no mechanism to do this, if the routes have parameters in them (like :id, etc) or if they have nesting (given /foo/bar, the middleware for /foo has no knowledge of /bar and vice-versa).
Is there a plan to get this merged? |
Can someone please give any timeline on when this could be merged? Anything blocking this to be completed? |
Nothing blocking AFAIK, there are just higher priorities. If you are interested in helping out you can take a look at these and start participating in the project: https://github.com/expressjs/express/blob/master/Contributing.md More people helping collaborate and traige issues would unblock the core team and allow us to spend more time on moving these features forward. Thanks in advance for your help! |
I would love this feature, as we're trying to expose Prometheus metrics based on the resolved route, rather than the incoming URL and normalizing it (which is very error prone). |
@saasen, my original interest in this feature was the exact same as your use case. If you are looking for a good solution which is simple and does not have many edge cases, you can do what I did in that app: const onFinished = require('on-finished')
function routeMetrics (route) {
return [route, (req, res) => {
onFinished(res, (err) => {
reportMetric(err, route)
})
}]
}
app.get(routeMetrics('/:foo'), routeHandlerMiddleware) The only thing to be aware of with a solution like this is that if a request would match two routes and both get run, both would report. You can prevent this if it is a concern for your app by setting a flag on |
@wesleytodd: Would this work when defining routes inside a Router as well? AFAIK, the route resolved inside a Router doesn't contain the "parent"-route. |
For the folks who keep asking when it will be merged / what is blocking: there are open review issues at the top that haven't been addressed yet. |
@saasen Hm, good question. Without actually trying that I am guessing no and that you would need to use a whole express app which has a @dougwilson Oh yeah, I guess I did open a review! I wonder if @ajfranzoia is interested in making those updates? If not I might be able to find some time soon to take this over and clean it up. |
I rebased these changes into #86. But it's mostly unchanged from this PR. |
Sorry for the noise, but wanted to mark off all of the feedback from @wesleytodd to ensure that it's incorporated into #86. |
closes pillarjs#34 closes pillarjs#85
closes pillarjs#34 closes pillarjs#85
closes pillarjs#34 closes pillarjs#85
Closing this in favor of the progress being made in #86 |
I'm transplanting this PR from the original I made at expressjs/express#2864 (issue discussed at expressjs/express#2501).
It allows to store every matched route in a request when travelling through nested routes. This may be useful for logging, ACL checks, etc.
So, for example, if you have your routing set like this:
A request for the URL
/foo/10/bar/baz/30
will set an array of matched routes in the request object like this:Let me know if there is anything that needs to be modification, unmeaningful variable names, etc.