# Using Data Transfer Objects (DTOs)

Custom Resources screencast
Watch the Custom Resources screencast

As stated in [the general design considerations](design.md), in most cases [the DTO pattern](https://en.wikipedia.org/wiki/Data_transfer_object) should be implemented using an API Resource class representing the public data model exposed through the API and [a custom State Provider](state-providers.md). In such cases, the class marked with `#[ApiResource]` will act as a DTO. However, it's sometimes useful to use a specific class to represent the input or output data structure related to an operation. These techniques are useful to document your API properly (using Hydra or OpenAPI) and will often be used on `POST` operations. ## Implementing a Write Operation With an Input Different From the Resource Using an input, the request body will be denormalized to the input instead of your resource class. ```php */ final class UserResetPasswordProcessor implements ProcessorInterface { /** * @param UserResetPasswordDto $data * * @throws NotFoundHttpException */ public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): User { if ('user@example.com' === $data->email) { return new User(email: $data->email, id: 1); } throw new NotFoundHttpException(); } } ``` In some cases, using an input DTO is a way to avoid serialization groups. ## Use Symfony Messenger With an Input DTO Let's use a message that will be processed by [Symfony Messenger](https://symfony.com/components/Messenger). API Platform has an [integration with messenger](../symfony/messenger.md), to use a DTO as input you need to specify the `input` attribute: ```php */ final class BookRepresentationProvider implements ProviderInterface { public function provide(Operation $operation, array $uriVariables = [], array $context = []): AnotherRepresentation { return new AnotherRepresentation(); } } ``` ## Implementing a Write Operation With an Output Different From the Resource For returning another representation of your data in a [State Processor](./state-processors.md), you should specify your processor class in the `processor` attribute and same for your `output`. ```php ``` Here the `$data` attribute represents an instance of your resource. ```php */ final class BookRepresentationProcessor implements ProcessorInterface { /** * @param Book $data */ public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): AnotherRepresentation { return new AnotherRepresentation( $data->getId(), $data->getTitle(), // etc. ); } } ```