From e8f3dbe1c5c663ca9f4d46db39862c1c9458572a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Pineau?= Date: Tue, 26 Dec 2017 17:30:10 +0100 Subject: [PATCH 1/2] Added basic doc for dealing with DTO --- core/dto.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++ index.md | 1 + 2 files changed, 115 insertions(+) create mode 100644 core/dto.md diff --git a/core/dto.md b/core/dto.md new file mode 100644 index 00000000000..e6160c5e30a --- /dev/null +++ b/core/dto.md @@ -0,0 +1,114 @@ +# Handling Data Transfer Objects (DTOs) + +## How to use a DTO for Writing + +Sometimes it's easier to use a DTO than an Entity when performing simple +operation. For example, the application should be able to send an email when +someone has lost its password. + +So let's create a basic DTO for this request: + +```php +namespace App\Api\Dto; + +use ApiPlatform\Core\Annotation\ApiResource; +use Symfony\Component\Validator\Constraints as Assert; + +/** + * @ApiResource( + * collectionOperations={ + * "post"={ + * "method"="POST", + * "path"="/users/forgot-password-request", + * }, + * }, + * itemOperations={}, + * ) + */ +final class ForgotPasswordRequest +{ + /** + * @Assert\NotBlank() + * @Assert\Email() + */ + public $email; +} +``` + +In this case, we disable all operations except `POST`. + +Then, thanks to [the event system](events.md), it's possible to intercept the +`POST` request and to handle it. + +First, an event subscriber is needed: + +```php +userManager = $userManager; + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::VIEW => ['sendPasswordReset', EventPriorities::POST_VALIDATE], + ]; + } + + public function sendPasswordReset(GetResponseForControllerResultEvent $event) + { + $request = $event->getRequest(); + + if ('api_forgot_password_requests_post_collection' !== $request->attributes->get('_route')) { + return; + } + + $forgotPasswordRequest = $event->getControllerResult(); + + $user = $this->userManager->findOneByEmail($forgotPasswordRequest->email); + + // We do nothing if the user does not exist in the database + if ($user) { + $this->userManager->requestPasswordReset($user); + } + + $event->setResponse(new JsonResponse(null, 204)); + } +} +``` + +Then this class should be registered as a service, then tagged. + +If service autowiring and autoconfiguration are enabled (it's the case by +default), you are done! + +Otherwise, the following configuration is needed: + +```yaml +# app/config/services.yml + +services: + + # ... + + 'App\Api\EventSubscriber\UserSubscriber': + arguments: + - '@app.manager.user' + tags: [ 'kernel.event_subscriber' ] +``` diff --git a/index.md b/index.md index 24e46d44fb7..76ccd687cad 100644 --- a/index.md +++ b/index.md @@ -112,6 +112,7 @@ 1. [Overall Process](core/serialization.md#overall-process) 2. [Available Serializers](core/serialization.md#available-serializers) 3. [Decorating a Serializer and Add Extra Data](core/serialization.md#decorating-a-serializer-and-add-extra-data) +27. [Handling Data Transfer Objects (DTOs)](core/dto.md) ## The Schema Generator Component: Generate Data Models from Open Vocabularies From 3922ad0cd8dff52b7661569fb73410de8a1e6a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 27 Dec 2017 10:54:09 +0100 Subject: [PATCH 2/2] Update dto.md --- core/dto.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/dto.md b/core/dto.md index e6160c5e30a..4d240e83a61 100644 --- a/core/dto.md +++ b/core/dto.md @@ -9,6 +9,8 @@ someone has lost its password. So let's create a basic DTO for this request: ```php +// api/src/Api/Dto/ForgotPasswordRequest.php + namespace App\Api\Dto; use ApiPlatform\Core\Annotation\ApiResource; @@ -44,6 +46,7 @@ First, an event subscriber is needed: ```php