-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing] Add {foo:bar}
syntax to define a mapping between a route parameter and its corresponding request attribute
#54720
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
Conversation
6a0f6b0
to
7a12e25
Compare
{foo:bar}
syntax to define a mapping between a route parameter and its corresponding attribute{foo:bar}
syntax to define a mapping between a route parameter and its corresponding request attribute
7a12e25
to
b2b5505
Compare
…parameter and its corresponding request attribute
b2b5505
to
1e091b9
Compare
Thank you @nicolas-grekas. |
… favor of mapped route parameters (nicolas-grekas) This PR was merged into the 7.1 branch. Discussion ---------- [DoctrineBridge] Deprecate auto-mapping of entities in favor of mapped route parameters | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | no | New feature? | yes | Deprecations? | | Issues | Fix #50739 | License | MIT Auto-mapping of entities on controllers is a foot-gun when multiple entities are listed on the signature of the controller. This is described extensively by e.g. `@stof` in the linked issue and in a few others. The issue is that we try to use all request attributes to call a `findOneBy`, but when there are many entities, there can be an overlap in the naming of the field/associations of both entities. In this PR, I propose to deprecate auto-mapping and to replace it with mapped route parameters, as introduced in #54720. If we go this way, people that use auto-mapping to e.g. load a `$conference` based on its `{slug}` will have to declare the mapping by using `{slug:conference}` instead. That makes everything explicit and keeps a nice DX IMHO, by not forcing a `#[MapEntity]` attribute for simple cases. Commits ------- a49f9ea [DoctrineBridge] Deprecate auto-mapping of entities in favor of mapped route parameters
Thank you @nicolas-grekas for this useful addition. I didn't find a doc update. Did I miss it or are you welcoming one ? |
We have one here It not merged yet |
Hi @fabpot , @nicolas-grekas Will this new feature be added to the Symfony 5.4 and 6.4 ? |
No, new features are only added to the branch that is currently in development. Old feature versions do only receive bugfixes and security patches. |
…ameter (eltharin) This PR was squashed before being merged into the 7.3 branch. Discussion ---------- [Routing] Add alias in `{foo:bar}` syntax in route parameter | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | License | MIT Since #54720 we can/have to write route parameters with "destination" as slug:bar, but if we have two properties with same name example : `/search-book/{name:author}/{name:category}` we get the error message : Route pattern "/search-book/{name}/{name}" cannot reference variable name "name" more than once. Actually to prevent this error we have to use MapEntity as : ```php public function bookSearch( #[MapEntity(mapping: ['authorName' => 'name'])] Author $author, #[MapEntity(mapping: ['categoryName' => 'name'])] Category $category): Response { ``` and we have to remove Mapped Route Parameters : `#[Route('/search-book/{authorName}/{categoryName}')` This PR proposal is to remove MapEntity attributes and keep Mapped Route Parameters by adding an alias on it : `/search-book/{authorName:author.name}/{categoryName:category.name}` With that, EntityValueResolver will search name in author Entity and name in Category Entity. We can have url with : `{{ path('bookSearch', {authorName: 'KING', categoryName: 'Horror'}) }}` Commits ------- 4e2c638 [Routing] Add alias in `{foo:bar}` syntax in route parameter
…ameter (eltharin) This PR was squashed before being merged into the 7.3 branch. Discussion ---------- [Routing] Add alias in `{foo:bar}` syntax in route parameter | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | License | MIT Since symfony/symfony#54720 we can/have to write route parameters with "destination" as slug:bar, but if we have two properties with same name example : `/search-book/{name:author}/{name:category}` we get the error message : Route pattern "/search-book/{name}/{name}" cannot reference variable name "name" more than once. Actually to prevent this error we have to use MapEntity as : ```php public function bookSearch( #[MapEntity(mapping: ['authorName' => 'name'])] Author $author, #[MapEntity(mapping: ['categoryName' => 'name'])] Category $category): Response { ``` and we have to remove Mapped Route Parameters : `#[Route('/search-book/{authorName}/{categoryName}')` This PR proposal is to remove MapEntity attributes and keep Mapped Route Parameters by adding an alias on it : `/search-book/{authorName:author.name}/{categoryName:category.name}` With that, EntityValueResolver will search name in author Entity and name in Category Entity. We can have url with : `{{ path('bookSearch', {authorName: 'KING', categoryName: 'Horror'}) }}` Commits ------- 4e2c6386912 [Routing] Add alias in `{foo:bar}` syntax in route parameter
…ameter (eltharin) This PR was squashed before being merged into the 7.3 branch. Discussion ---------- [Routing] Add alias in `{foo:bar}` syntax in route parameter | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | License | MIT Since symfony/symfony#54720 we can/have to write route parameters with "destination" as slug:bar, but if we have two properties with same name example : `/search-book/{name:author}/{name:category}` we get the error message : Route pattern "/search-book/{name}/{name}" cannot reference variable name "name" more than once. Actually to prevent this error we have to use MapEntity as : ```php public function bookSearch( #[MapEntity(mapping: ['authorName' => 'name'])] Author $author, #[MapEntity(mapping: ['categoryName' => 'name'])] Category $category): Response { ``` and we have to remove Mapped Route Parameters : `#[Route('/search-book/{authorName}/{categoryName}')` This PR proposal is to remove MapEntity attributes and keep Mapped Route Parameters by adding an alias on it : `/search-book/{authorName:author.name}/{categoryName:category.name}` With that, EntityValueResolver will search name in author Entity and name in Category Entity. We can have url with : `{{ path('bookSearch', {authorName: 'KING', categoryName: 'Horror'}) }}` Commits ------- 4e2c6386912 [Routing] Add alias in `{foo:bar}` syntax in route parameter
While trying to improve the DX of auto-mapping Doctrine entities and from the discussion on the related PR #54455, I realized that it would help a lot if we were able to express a mapping between route parameter and request attributes directly into route definitions.
This PR adds the ability to define a route with such a mapping:
#[Route('/conference/{slug:conference}')]
On the router side, the side-effect of this is just that a new
_route_mapping
array is returned by the matcher, and nothing else.Then, in HttpKernel's RouterListener, we use that parameter to map route parameters to request attributes. On their turn, argument resolvers will just see a request attribute named
conference
. But they can also now read the_route_mapping
attribute and decide to do more tailored things depending on the mapping.For example, one could define this route:
#[Route('/conference/{id:conference}/{slug:conference}')]
This would be turned into a request attribute named
conference
with['id' => 'the-id', 'slug' => 'the-slug']
as content.This mapping concern already leaks into many value resolver attributes (see their "name" property).
For the entity value resolver, this feature will allow deprecating auto-mapping altogether, and will make things more explicit.