-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[HttpKernel] Create Attributes #[MapRequestPayload]
and #[MapQueryString]
to map Request input to typed objects
#49138
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
87eb66c
to
a08be6b
Compare
#[MapQueryString
and #[MapRequestContent]
to map Request input to typed objects
#[MapQueryString
and #[MapRequestContent]
to map Request input to typed objects#[MapQueryString]
and #[MapRequestContent]
to map Request input to typed objects
078781e
to
b3bbe43
Compare
It looks like your committer email is not associated with your Github account |
Was this a coincidence that we both did something similar or did you create this afterwards? |
b3bbe43
to
4e8cb8e
Compare
@OskarStark thanx, fixed now, please check @ruudk it is similar but has few differences comparing to your implementation. I've updated PR description to highlight the differences. BTW anybody know how to fix unrelated fabbot failure? |
this looks promising :)
what about deserializing errors vs. ValidationFailedException? Does either produce a 400 bad request? is only the latter i18n friendly? |
My idea was start from something like simple implementation in this PR and improve it later before 6.3 release.
|
4e8cb8e
to
1b619a2
Compare
i like a simple implementation as first iteration, but i like http/i18n compatibility more ;) |
19069b1
to
052f625
Compare
Your PR also makes this one #47425 obsolete. |
052f625
to
25e7d70
Compare
I would use a separate exception, which builds on the |
cf31004
to
a2b5f96
Compare
src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php
Show resolved
Hide resolved
f18decf
to
50c06d1
Compare
50c06d1
to
d3bdaea
Compare
…String]` to map Request input to typed objects
d3bdaea
to
d987093
Compare
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 just made some minor and final changes:
https://github.com/symfony/symfony/compare/50c06d123c1c0539a1e47cb202bce6d430247ff7..d987093a538c70fc4a2d01b046913a2820341699
Thank you @Koc. |
Note that if there are remaining topics to discuss (naming?), we're still in feature freeze so we can do any changes! |
@nicolas-grekas thanx! I'm fine with |
…nd validation group (renanbr) This PR was merged into the 6.3 branch. Discussion ---------- [HttpKernel] Enhance MapRequestPayload adding format and validation group | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Implements #49138 (comment) | License | MIT | Doc PR | not yet This PR enhances `MapRequestPayload` (merged via #49138) by allowing users to restrict format and pick validation groups. ```php # src/Controller/HelloController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\HttpKernel\Attribute\MapRequestPayload; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Validator\Constraints as Assert; #[AsController] final class HelloController { #[Route('/hello', methods: ['POST'])] public function __invoke( #[MapRequestPayload(acceptFormat: 'json', validationGroups: 'strict')] MyObject $object, ): Response { // framework will... // 1. deserialized HTTP content from json, and throws exception in case of mismatch // 2. validate ONLY constraint in the "strict" group, and throws exception in case of invalidation } } ``` Commits ------- 068fb4d [HttpKernel] Enhance MapRequestPayload adding format and validation group
…group (renanbr) This PR was merged into the 6.3 branch. Discussion ---------- [HttpKernel] Enhance MapQueryString adding validation group | Q | A | ------------- | --- | Branch? | 6.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | continuity of #50029 and #49138 | License | MIT | Doc PR | n/a - Introduces `$validationGroups` property to the `MapQueryString` attribute to work as same as in `MapRequestPayload` - Renames `MapQueryString` property `$context` to `$serializationContext` to harmonize with `MapRequestPayload` ```php # src/Controller/HelloController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\HttpKernel\Attribute\MapQueryString; use Symfony\Component\Routing\Annotation\Route; #[AsController] final class HelloController { #[Route('/hello', methods: ['GET'])] public function __invoke( #[MapQueryString(validationGroups: 'strict')] MyObject $object, ): Response { // ... } } ``` Commits ------- 8aad8b9 [HttpKernel] Enhance MapQueryString adding validation group
… argument attribute (renedelima) This PR was merged into the 7.1 branch. Discussion ---------- [HttpKernel] Introduce `#[MapUploadedFile]` controller argument attribute | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | #52678, #49138 | License | MIT | Doc PR | - ## Usage Example ```php # src/Controller/UserPictureController.php namespace App\Controller; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\HttpKernel\Attribute\MapUploadedFile; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Validator\Constraints as Assert; #[AsController] final class UserPictureController { #[Route('/user/picture', methods: ['PUT'])] public function __invoke( #[MapUploadedFile( new Assert\File(mimeTypes: ['image/png', 'image/jpeg']), )] ?UploadedFile $picture, ): Response { return new Response('Your picture was updated'); } } ``` ```php # src/Controller/UserDocumentsController.php namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\HttpKernel\Attribute\MapUploadedFile; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Validator\Constraints as Assert; final class UserDocumentsController { #[Route('/user/documents', methods: ['PUT'])] public function __invoke( #[MapUploadedFile( new Assert\File(mimeTypes: ['application/pdf']) )] array $documents ): Response { return new Response('Thanks for sharing your documents'); } } ``` ```php # src/Controller/UserDocumentsController.php namespace App\Controller; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\HttpKernel\Attribute\MapUploadedFile; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Validator\Constraints as Assert; final class UserDocumentsController { #[Route('/user/documents', methods: ['PUT'])] public function __invoke( #[MapUploadedFile( new Assert\File(mimeTypes: ['application/pdf']) )] UploadedFile ...$documents ): Response { return new Response('Thanks for sharing your documents'); } } ``` Commits ------- b85dbd0 [HttpKernel] Add MapUploadedFile attribute
Yet another variation of how we can map raw Request data to typed objects with validation. We can even build OpenApi Specification based on this DTO classes using NelmioApiDocBundle.
Usage Example 🔧
#[MapRequestPayload]
#[MapQueryString]
Exception handling 💥
ConstraintViolationList
.Comparison to another implementations 📑
Differences to #49002:
Differences to #49134:
$request->getContent()
and$request->request->all()
mappingDifferences to #45628:
$request->request->all()
and$request->query->all()
mappingBonus part 🎁
UnsupportedFormatException
which thrown when there is no decoder for a given format