Hi All, I'm trying to wrap my head around the rest...
# box-products
s
Hi All, I'm trying to wrap my head around the rest-hmvc app... running through the docs here: https://coldbox.ortusbooks.com/digging-deeper/recipes/building-rest-apis I can't seem to get the URL routes working. I have the following route defined in /config/Router.cfc and can see it in /route-visualizer
Copy code
// User Resource
        route( "/api/v1/user/:userID" )
            .withAction( {
                GET    = 'view',
                POST   = 'save',
                PUT    = 'save',
                DELETE = 'remove'
            } )
            .toHandler( "api.v1.user" );
For example, a PUT to the conventional URL works:
/api/v1/user/save/userid/55
But, a PUT to
/api/v1/user/55
throws an error with message "Action '55' could not be found". Which means coldbox skipped right over the route definition, right?
s
One mistake we still make from time to time is that we forget routes need to go from most explicit to least explicit, i.e. if you have a
route( "/api/v1/user")
above that route you listed, it will match that one first
☝️ 1
Because the syntax for what you have looks correct for what you want
although if this is the router inside of the
v1
module I don't think you need
api.v1.user
for
toHandler
- just
user
and if it's not the router inside the v1 module, that might also be the issue
s
Ah, makes sense; I wasn't considering the order. This is /config/Router.cfc so not in the v1 module. I'll make some changes.
s
Make sure to disable convention routing in your module router then, since it will try that router first
1
s
I see three separate router files in the following folders /config, /modules_app/api/config, /modules_app/api/modules_app/v1/config. The one under api/config is empty. The one under v1/config has specific example API routes for authentication and secured routes so I assume that's the one I should use? And to disable convention routing I'd just remove the
route( "/:handler/:action" ).end();
line in /config/Router.cfc and make sure the v1 file has that as the last line, correct?
still struggling with this. Looks like
...the base skeleton="rest-hmvc" doesn't load any Router.cfc files in the modules api or v1. only /config/Router.cfc gets loaded and can be seen in /route-visualizer
s
We bolted it onto an existing app so we may have manually pulled the template from github. It was also two years ago so it may have changed. I don't think you "have to" use the module's router, but we do just to keep our API routes distinct from our legacy app routes
s
when I change
Copy code
// User Resource
        route( "/api/v1/user/:userID" )
            .withAction( {
                GET    = 'view',
                POST   = 'save',
                PUT    = 'save',
                DELETE = 'remove'
            } )
            .toHandler( "v1:user" );
TO...
Copy code
// User Resource
        route( "/who/:userID" )
            .withAction( {
                GET    = 'view',
                POST   = 'save',
                PUT    = 'save',
                DELETE = 'remove'
            } )
            .toHandler( "v1:user" );
POST to URL "/who/55" works fine and is mapped to /api/v1/user/save/userID/55 routes defined with "api/v1/user/:userID" do not match the URL /api/v1/user/55 even though it looks like it should in route-visualizer. Instead that URL is caught by the default handler/action/ route. I'll keep playing and reading but I feel like I'm missing or not understanding some fundamental piece of routing in coldbox.
s
Routing is a bit of a black art I think the culprit is the
api/v1
part of the route. That should be the route to the module, not to the event. All of our routes are part of our v1 Router.cfc and look like
Copy code
.route( "/eligibilityRules" )
        .withAction( {
            GET = 'list'
        })
        .toHandler( "eligibilityRules" )
There isn't any reference to the module path.
so maybe having a v1-specific module router is less optional than it seems?
s
I would like to use the module's router because that makes sense to me. However, in the skeleton, the module router with...
Copy code
// API Authentication Routes
		post( "/login", "Auth.login" );
		post( "/logout", "Auth.logout" );
		post( "/register", "Auth.register" );

		// API Secured Routes
		get( "/whoami", "Echo.whoami" );
...aren't loaded into coldbox (at least not visible in route-visualizer) and routes don't work
s
I do feel like the point of the HVMC architecture is that you wouldn't use a parent router, you'd use the module router
s
Yes!
s
It's strange that they aren't loaded. Are they in config/Router.cfc? We have no routing info at all in ModuleConfig.cfc
s
Maybe I should start from scratch to learn routing instead of using the hmvc-template. It could be just a configuration in the template that I'm missing/don't understand.
uh... sorry... let me check. I'm stepping on your replies.
yes, so...
Copy code
coldbox create app skeleton="rest-hmvc"
server start --rewritesEnable
the v1 module config/Router.cfc doesn't get loaded and routes defined in it don't work and I can't figure out why. The only routes that work are in the root /config/Router.cfc that contains the /healthcheck route and the default conventions route.
c
@Sam Scott do you have this set in your moduleConfig.cfc files:
this.entryPoint = "/mymodule";
?
s
yes, so I think I'm making progress...
My issue was using a handler named "user.cfc"
c
Your
api
module probably needs
this.entryPoint = "/api";
and your
api/v1
module probably needs
this.entryPoint = "/v1";
or maybe
this.entryPoint = "/api/v1";
(not sure which).
s
Yes, thanks @cfvonner, those look good.
there is a user.cfc and usermodel.cfc in the model directory... maybe conflicting with my api handler "user.cfc"?
As soon as I changed my handler name to "endUser.cfc" the routes started working.
I still expected the routes to show up in /route-visualizer but they do not so that was also throwing me off.
The endpoints are showing in RELAX but not in /route-visualizer. Any tips on getting all routes to display in the visualizer?
@sknowlton Thanks for your help, today. Things are (mostly) working as expected!
I'm such a dummy... 😁 I completely missed the blue "open router" button for each module on the route-visualizer page. I was only looking at the order and pattern+regex columns and trying to find routes using the filter at the top of the page.