-
-
Notifications
You must be signed in to change notification settings - Fork 328
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
Fixed a bug in binding the URL parameters for API resource routes #489
Closed
Khaled-Farhat
wants to merge
3
commits into
knuckleswtf:master
from
Khaled-Farhat:fix-default-url-params
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that we don't want this. This sued to be the case before, but a number of people pointed out that it was unintuitive. It makes sense from the Laravel perspective, since we know about route model binding, but the reader of the API docs wants to know the value that goes in there (the user ID), not just the model.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that using only the model name is not intuitive, but that is not the case when using type-hinted variables in the controller action.
In the test case you pointed out, there are no type-hinted variables in the controller action, and that is the reason why the URL parameter was
user
.But when using type-hinted variables in the controller action, the URL parameter will be
user_id
(oruser_slug
if the developer customized the route key name toslug
). I think this behavior satisfies both the API docs reader and the developer since he can customize the route key name.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I don't agree there.
Yes, but will he? It would be annoying to ask a developer to go through their routes and add
:id
for every parameter they use. Especially as Laravel defaults to using theid
as the route key, it makes no sense that we can't.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From your original comment:
I think we should focus on this. See if the model has
getRouteKeyName()
defined or a custom key in the route, and use that. Otherwise, we stick toid
. We may just need to move the order of operations around to achieve this.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you want to stick with the
id
even for varaibles that are not type-hinted? as theid
will be used by default for the type-hinted variables becausegetRouteKeyName()
is defined inIlluminate\Database\Eloquent\Model
to return theid
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. The current behavior:
What I will do in my new pull request, is to add a new step before the second step to check if there is a type-hinted variable in the controller action with the same name as the route segment name. This is the same behavior as the laravel implicit binding:
Case 1: If there is an inline binding in the route.
Current behavior: use inline binding. Current URIs:
posts/{slug}
andposts/{post_slug}/comments
.The new behavior is the same.
Case 2: No inline binding exists, but model binding exists.
Assume that
Post@getRouteKeyName
returnsslug
, andPostController@show
uses model binding (Post $post
).Current behavior: use the
id
for resource parameters, and keep the same name for non-resource parameters.Current URIs:
posts/{id}
andposts/{post}/comments
.New behavior: call
getRouteKeyName()
.New URIs:
posts/{slug}
andposts/{post_slug}/comments
.Case 3: Resource route parameter. No inline binding exists. No model binding exists.
Assume that
PostController@show
does not use model binding.Current behavior: use the
id
. Current URI:posts/{id}
.The new behavior is the same.
Case 4: Non-Resource route. No inline binding exists. No model binding exists.
Current behavior: keep the same parameter name. Current URI:
posts/{post}
.The new behavior is the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have another question about the testing, Is there a problem if I added 3 fixtures to test the new behavior?
The fixtures I want to add:
TestPost
model that overridesgetRouteKeyName()
to returnslug
.TestPostController
with one method that has a type-hinted variable (TestPost $post
). I will use it to test generating the URIposts/{slug}
.TestPostUserController
with one method that uses two type-hinted variables (TestPost $post, TestUser $user
). I will use it to test generating the URIposts/{post_slug}/users/{id}
from a nested resource route.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that sounds good. We probably need to clean up the code to make it less confusing, perhaps with some inline documentation of the examples. Also, I think the responsibility is half-shared; IIRC, there's somewhere else in the code where the URI is "fixed" slightly, which may change the results from here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, you can add whatever you need.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I just noticed your PR edits both locations (GetFromLaravelAPI and ExtractedEndpointData), which is good. I wish there was a way for that logic to remain in one place (ideally the GetFromLaravelAPI strategy), but the URL is one of the basic things about the endpoint, so it needs to be fixed as early as possible. Plus, even though they can, I'd prefer to avoid modifying the endpoint object directly inside a strategy.