@@ -213,3 +213,108 @@ final class BookRepresentationProcessor implements ProcessorInterface
213213 }
214214}
215215```
216+
217+ ## Implementing one custom state provider with DTOs to support Get and GetCollection methods
218+
219+ We have a state provider named ` BookProvider ` which retrieves our data to serve them in our API using DTOs.
220+ If we want to combine both Get and GetCollection methods into a single state provider as follows:
221+
222+ ``` php
223+ <?php
224+ // api/src/Resource/Book.php with Symfony or app/Resource/Book.php with Laravel
225+
226+ declare(strict_types=1);
227+
228+ namespace App\Resource;
229+
230+ use ApiPlatform\Metadata\ApiResource;
231+ use App\State\BookProvider;
232+ use ApiPlatform\Metadata\Get;
233+ use ApiPlatform\Metadata\GetCollection;
234+ use Doctrine\ORM\Mapping as ORM;
235+ use Symfony\Component\Validator\Constraints as Assert;
236+
237+ #[Get(provider: BookProvider::class)]
238+ #[GetCollection (provider: BookProvider::class)]
239+ final class Book
240+ {
241+ #[ORM\Id]
242+ #[ORM\GeneratedValue]
243+ #[ORM\Column(type: 'integer')]
244+ private ?int $id = null;
245+
246+ #[ORM\Column(type: 'string', length: 255)]
247+ #[Assert\NotBlank]
248+ private string $title;
249+
250+ // Other fields, accessors and mutators...
251+ }
252+ ```
253+
254+ To do that, we can create a state provider for both cases using this:
255+
256+ ``` php
257+ <?php
258+ // api/src/State/BookProvider.php with Symfony or app/State/BookProvider.php with Laravel
259+
260+ declare(strict_types=1);
261+
262+ namespace App\Resource;
263+
264+ use ApiPlatform\Metadata\ApiResource;
265+ use ApiPlatform\State\ProviderInterface;
266+ use ApiPlatform\Doctrine\Orm\State\CollectionProvider;
267+
268+ final class BookProvider implements ProviderInterface
269+ {
270+ public function __construct(
271+ #[Autowire(service: CollectionProvider::class)]
272+ private readonly ProviderInterface $collectionProvider,
273+ ) {}
274+
275+ public function provide(Operation $operation, array $uriVariables = [], array $context = []): ?PostalAddress
276+ {
277+ $resources = $this->collectionProvider->provide($operation, $uriVariables, $context);
278+
279+ $dtos = [];
280+ foreach ($resources as $resource){
281+ $dtos[] = new Book(
282+ $resource->id,
283+ $resource->title,
284+ // ...
285+ )
286+ }
287+
288+ return $dtos;
289+ }
290+ }
291+ ```
292+
293+ > [ !TIP]
294+ > For more information and other advanced options, refer to the [ screencast here] ( #using-data-transfer-objects-dtos ) .
295+
296+ ## DTO without response
297+
298+ Sometimes we need DTOs to process something, but we don't need to send an object in response.
299+ Assuming that, we can disable the output for our API Resource using the following code:
300+
301+ ``` php
302+ <?php
303+ // api/src/Resource/Book.php with Symfony or app/Resource/Book.php with Laravel
304+
305+ declare(strict_types=1);
306+
307+ namespace App\Resource;
308+
309+ use ApiPlatform\Metadata\ApiResource;
310+ use App\Dto\BookInput;
311+
312+ #[ApiResource(
313+ input: BookInput::class,
314+ output: false, // Disables the response
315+ )]
316+ final class Book
317+ {
318+ // ...
319+ }
320+ ```
0 commit comments