Thanks so much for debugging this and providing this helpful info Summarizing for myself:
The specific route combination that reproduces the issue:
get 'catalogs/:id', to: 'catalogs#show'
post 'catalogs/:catalog_id/apps', to: 'catalogs/apps#create'
Think see what’s going on here. This is because API Gateway only allows one path variable under the same in the parent route node. Here’s a reproduction of the issue manually.
RE: 1. Instruct the user that in routes.rb path variables on the same level should be called the same.
- Yup, think we should add docs noting this API Gateway constraint and how to currently avoid it. That’s a big win and will help save folks time right now.
- Upon route building, check for “multiple variable part path definitions” that collide and error with an informative message to the user. So the user finds out about this early as we can help with the process, locally. Even before they try to deploy. When they deploy check the same logic and also provide same information message in case they deploy without checking locally. Something like
API Gateway only allows one unique variable path. [screenshot link]. You must use the same variable name within the same parent route path. Example: /posts/:id
and /posts/:post_id/reveal
should both be /posts/:id
and /posts/:id/reveal
.
Something like that, the message can be improved and can tell the users how to fix it.
Created an issue: https://github.com/tongueroo/jets/issues/143
RE: Unfortunately, this won’t fix the rename issue and deploy will still fail if someone tries to rename the path variable. Is there a way around that?
So Jets actually addresses the rename issue for most cases already rest_api/change_detection.rb Was a pretty annoying issue so I introduced route change detection in version 1.2 CHANGELOG At the same time, also introduced Custom Domain support and Automated Blue-Green Deployments. Since when routes changed Jets builds an entirely new API Gateway with a new endpoint. Custom domains help to make make it transparent.
But you’re right, the rename detection does not properly detect the case of a path variable rename. So that needs to be improved.
Created as issue: https://github.com/tongueroo/jets/issues/144
RE: 2. In the deployment template, map routes.rb variable names to something constant like var_X(/apps/:app_id/comments/:id to /apps/:var_1/comments/:var_3) where X is a resource depth index (/0/1/2/3). This will fix the renaming issue.
Naturally, Jets would need a translator encoded in the base controller to translate it back. I’m not sure if it will not introduce any new issues on the road.
RE: handling multiple variable part path definitions with a jets routing translation layer.
Unsure. Maybe one day API Gateway will add support for multiple path variables. These things are so hard to tell without actually implementing enough of it before we can ascertain if it’s worth it. Sometimes I’ve even built prototypes successfully, and then decided to throw it all away in the end. The complexity and maintenance is sometimes not worth the feature
If we did do add variable path support internally to Jets. Think this would be a simpler approach. Take:
get 'catalogs/:id', to: 'catalogs#show'
post 'catalogs/:catalog_id/apps', to: 'catalogs/apps#create'
Translate it to:
get 'catalogs/:multiple', to: 'catalogs#show'
post 'catalogs/:multiple/apps', to: 'catalogs/apps#create'
So API Gateway would create catalogs/:multiple
as the resource path successfully. multiple
would be a reserved path variable name for this special case.
Then internally within Jets, route the :multiple variable back to original routes and parameters using the routes definition.
Could also be all in vain as API Gateway could add multiple variable route support. Gut tells me it might not be worth it? Will have to play with it more to really understand this better.