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

Reopening #223 Which route was matched? #246

Open
kunalgolani opened this issue Feb 18, 2016 · 7 comments
Open

Reopening #223 Which route was matched? #246

kunalgolani opened this issue Feb 18, 2016 · 7 comments

Comments

@kunalgolani
Copy link

The PR closing #223 added this._matchedRoute, but there's still a bug.

if you add another similar but more generic route, this._matchedRoute always gives the more generic route instead of the actually matched more specific one

router.get('/users/:id', function *() {
    // this._matchedRoute is '/:username/:id'
});
router.get('/:username/:id', function *() {
    // this._matchedRoute is '/:username/:id'
});
@bcho
Copy link

bcho commented Feb 22, 2016

+1 for this feature. Can we attach layer to context for inspecting inside the controller?

@jergason
Copy link
Collaborator

I think this._matchedRoute is always just the last layer that matched, and that is dependent on the order that you declare your routes in. Whoops!

@EyMaddis
Copy link

Same problem can occur for something like this:

router.get('/users/me',...) // should match first because of order
router.get('/users/:id',...)

probably relates to #231

@RobinQu
Copy link

RobinQu commented May 3, 2016

+1 this is a big surprise for a routing middleware...

@aobo-y
Copy link

aobo-y commented Sep 5, 2016

I have a customized 404 controller registered at the end which cause all this._matchedRoute to wildcard

router.get('/some/path', controller)

router.all('*', function* (){
  // behavior for not found
})

@jagij
Copy link

jagij commented Oct 12, 2018

This is still a problem today. Tested with versions 5.4.0 and 7.4.0.

Workaround:

	const getMatchedRoute = () => {
		/* Workaround for https://github.com/alexmingoia/koa-router/issues/246
		 * so we can't use ctx._matchedRoute.
		 * - cut off the query string from the path
		 * - get all path matches
		 * - filter those whose methods match
		 * - take the first one
		 */
		const url = ctx.request.url.split('?')[0];
		const matchedPaths = router.match(url).path;
		const matchingMethod = matchedPaths.filter(r => r.methods.includes(ctx.request.method));
		return (matchingMethod[0] || {}).path || '';
	};

Replace ctx by this when using koa < 2.0

@davidmz
Copy link

davidmz commented Apr 10, 2019

A simpler workaround, router holds all matches in ctx.matches array:

const matchedRoute = ctx.matched.find((layer) => layer.methods.includes(ctx.method)).path;

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

No branches or pull requests

9 participants