Skip to content
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

Getting matched route #14

Open
rightaway opened this issue Jul 11, 2019 · 9 comments
Open

Getting matched route #14

rightaway opened this issue Jul 11, 2019 · 9 comments

Comments

@rightaway
Copy link

Is there a way to get the matched route pattern as opposed to the actual url (ctx.request.url)?

Also this middleware appears near the end of all my middleware (after the ones that need to go before it like logging and permissions). But I'd like to be able to log the matched route pattern in the earlier middleware. Something like a router.getMatchedPattern function we could call at the beginning of our middleware to resolve the matched pattern which we can use throughout the other middleware. What do you think of such feature?

app.use(addToLogger(router.getMatchedPattern())
// lots of other middleware go here
app.use(othermiddleware)
app.use(router.routes())
@steambap
Copy link
Owner

I see no easy way to get the matched route pattern without hurting performance. However, PRs are welcome if you can fix it.

Since Koa middleware run in the order that they declared, if a middleware want to do something in the upstream middleware, it will require a lot of hack. I think a good middleware should be self-contained and has no black magic that can manipulate upstream middleware. Therefore, this feature should be in your Koa application, not in a module.

@rightaway
Copy link
Author

koa-tree-router is already taking ctx.request.url and looking through all routes to determine which one matches. If you could expose that function so we could call it ourselves, koa-tree-router middleware will remain self-contained with no black magic.

We can just call that exposed function in another middleware (only if we'd like to log the matched route pattern early in the middleware stack). No routing happens until koa-tree-router is reached, just as before. So no change for people who don't need this functionality.

The only downside would be that if I log the matched route pattern, the route resolution happens twice. But since this is already up to 11 times faster than koa-router it's no problem. Plus I wouldn't be logging it in all cases. And people who aren't logging it would see no performance penalty at all.

@steambap
Copy link
Owner

What is the function that you want the router to expose?

@rightaway
Copy link
Author

Something like router.getMatchedPattern(ctx), which uses ctx.request.url like /route/1 and returns the actual pattern that was matched, like /route/:param.

@steambap
Copy link
Owner

Let me think about it. Meanwhile, PRs are welcome.

@dosentmatter
Copy link

dosentmatter commented Jul 7, 2020

Can't you just prepend a middleware for each router[method]? You can also move the logic into reusable functions to avoid duplicate code.

// Replace this
router.get('/path', middleware)

// with
router.get('/path', addToLogger('/path'), middleware)

I think router.get('/path', middleware0, middleware1) is an undocumented feature, but I think it should work because handle accepts an array of functions. This feature is in koa-router.

An equivalent alternative is to use koa-compose:

router.get('/path', compose([addToLogger('/path'), middleware]))

@rightaway
Copy link
Author

@dosentmatter That's duplication as well. If you change /path it has to always be done in 2 places.

Plus giving us the ability to call a generic function like I've suggested can be used in several ways beyond this.

@dosentmatter
Copy link

dosentmatter commented Aug 15, 2020

@rightaway It is duplicate in my example, but I mentioned above

You can also move the logic into reusable functions to avoid duplicate code.

So you can have a helper function that takes the input path '/path' and feeds it into two places. It would also take as input the router method eg. get and the subsequent middleware.

This is just a workaround for the time being since the feature doesn't exist. Though it could be part of how this feature is eventually implemented.

@rightaway
Copy link
Author

As a workaround not a solution I understand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants