Issues with Router

I have two problems:

#1 First issue

Two routes in my Router.cfc:

get(
	"/products"
).to( "ProductController.search" ).end();

get(
	"/products/:id"
).to( "ProductController.get" ).end();

if i call:

http://localhost:62566/api/products/myId

router fires the first route (with “search” method). I expected for the second (with myId param after /products/)

If I reverse the two routes, it works fine.

I tried playing with:

setFullRewrites( true );
setLooseMatching( true );

but it doesn’t change anything.

I don’t understand if it’s correct behavior or a bug.

In Apache I have to use the string start (^) and string end ($) characters for an exact search of the string, or the character “=” before matching pattern.


#2 Second issue

This configuration of my Router.cfc causes an error:

get(
	"/products"
).to( "ProductController.search" ).end();
	
post(
	"/products"
).to('ProductController.create').end();

As you see, I have same url (“/products”) with different handler and verbs.

I call:
http://localhost:62566/api/products

I get this error:

EventHandlerNotRegisteredException
The event: ProductController.search is not a valid registered event.

If i change the verb or the url it works correctly.
I only encounter this problem inside a module.


Here you can download a test package.

Simple, from CommandBox, as you know:

install
server start

then point your browser to:
http://localhost:62566/api/products

I work with:

  • this.nullSupport = false;
  • Coldbox 7.0.0.2
  • Lucee: 5.4.0+80

Thank you very much.

/products will match everything that starts with /products, so it catches /products/myid as well as just /products

You need to put the most specific first.
That’s the way it works.

Its matching the start of the route, so each route with the same sections, need to be ordered most specifc to least

/products/:id can catch everything with an ID but ignore the rest
then
/products can catch everything else that got past the first route that matches the /products route.

Hope that helps.

1 Like

For your 2nd issue, I would maybe try the using .withAction() to combine both your get() and post() into one statement.

route( "/products" )
	.withAction( {
		GET : "search",
		POST : "create"
	} )
	.toHandler( "ProductController" );
2 Likes

thanks @gpickin!

I understood that the implementation of the rule is the same as that of apache, iis and other webservers.
I don’t understand the sense of not doing the exact match, but I adapt. :slight_smile:

thank you very much for helping!

Thanks @MikeR!
Route() solves my problem, works like a charm!

Many thanks! :slight_smile:

1 Like