You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -471,7 +471,8 @@ Symfony controllers extending the [`Symfony\Bundle\FrameworkBundle\Controller\Co
471
471
helper class.
472
472
473
473
However, API Platform recommends to use **action classes** instead of typical Symfony controllers. Internally, API Platform
474
-
implements the [Action-Domain-Responder](https://github.com/pmjones/adr) pattern (ADR), a web-specific refinement of [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller).
474
+
implements the [Action-Domain-Responder](https://github.com/pmjones/adr) pattern (ADR), a web-specific refinement of
Note: [the event system](events.md) should be preferred over custom controllers when applicable.
477
478
@@ -482,10 +483,199 @@ Thanks to the [autowiring](http://symfony.com/doc/current/components/dependency_
482
483
Symfony Dependency Injection container, services required by an action can be type-hinted in its constructor, it will be
483
484
automatically instantiated and injected, without having to declare it explicitly.
484
485
485
-
In the following example, the built-in `GET` operation is registered as well as a custom operation called `special`.
486
+
In the following examples, the built-in `GET` operation is registered as well as a custom operation called `special`.
486
487
The `special` operation reference the Symfony route named `book_special`.
487
488
488
-
Note: API Platform uses the first operation (with `GET` method) defined in `collectionOperations` to generate the IRI for this resource class. This means that as long as you dont want to overwrite the IRI for this resource class by intention, the default collection operation associated with the `GET` method should be the first operation defined inside collection operations.
489
+
Note: By default, API Platform uses the first `GET` operation defined in `collectionOperations` to generate the IRI for
490
+
a resource class.
491
+
492
+
### Recommended Method
493
+
494
+
First, let's create your custom operation:
495
+
496
+
```php
497
+
<?php
498
+
// api/src/Controller/BookSpecial.php
499
+
500
+
namespace App\Controller;
501
+
502
+
use App\Entity\Book;
503
+
504
+
class BookSpecial
505
+
{
506
+
private $myService;
507
+
508
+
public function __construct(MyService $myService)
509
+
{
510
+
$this->myService = $myService;
511
+
}
512
+
513
+
public function __invoke(Book $data): Book
514
+
{
515
+
$this->myService->doSomething($data);
516
+
517
+
return $data;
518
+
}
519
+
}
520
+
```
521
+
522
+
This custom operation behaves exactly like the built-in operation: it returns a JSON-LD document corresponding to the id
523
+
passed in the URL.
524
+
525
+
Here we consider that [autowiring](https://symfony.com/doc/current/service_container/autowiring.html) is enabled for
526
+
controller classes (the default when using the API Platform distribution).
527
+
This action will be automatically registered as a service (the service name is the same as the class name:
528
+
`App\Controller\BookSpecial`).
529
+
530
+
API Platform automatically retrieves the appropriate PHP entity using the data provider then deserializes user data in it,
531
+
and for `POST` and `PUT` requests updates the entity with data provided by the user.
532
+
By convention, the action's parameter must be called `$data`.
533
+
534
+
Services (`$myService` here) are automatically injected thanks to the autowiring feature. You can type-hint any service
535
+
you need and it will be autowired too.
536
+
537
+
The `__invoke` method of the action is called when the matching route is hit. It can return either an instance of
538
+
`Symfony\Component\HttpFoundation\Response`(that will be displayed to the client immediately by the Symfony kernel) or,
539
+
like in this example, an instance of an entity mapped as a resource (or a collection of instances for collection operations).
540
+
In this case, the entity will pass through [all built-in event listeners](events.md) of API Platform. It will be
541
+
automatically validated, persisted and serialized in JSON-LD. Then the Symfony kernel will send the resulting document to
542
+
the client.
543
+
544
+
The routing has not been configured yet because we will add it at the resource configuration level:
public function __invoke(Book $data): object // API Platform retrieves the PHP entity using the data provider then (for POST and
570
-
// PUT method) deserializes user data in it. Then passes it to the action. Here $data
571
-
// is an instance of Book having the given ID. By convention, the action's parameter
572
-
// must be called $data.
762
+
public function __invoke(Book $data): Book
573
763
{
574
764
$this->myService->doSomething($data);
575
765
576
-
return $data; // API Platform will automatically validate, persist (if you use Doctrine) and serialize an entity
577
-
// for you. If you prefer to do it yourself, return an instance of Symfony\Component\HttpFoundation\Response
766
+
return $data;
578
767
}
579
768
}
580
769
```
581
770
582
-
This custom operation behaves exactly like the built-in operation: it returns a JSON-LD document corresponding to the id
583
-
passed in the URL.
584
-
585
-
It is mandatory to set the `_api_resource_class` and `_api_item_operation_name` (or `_api_collection_operation_name` for a collection
771
+
It is mandatory to set `_api_resource_class` and `_api_item_operation_name` (or `_api_collection_operation_name` for a collection
586
772
operation) in the parameters of the route (`defaults` key). It allows API Platform and the Symfony routing system to hook
587
773
together.
588
774
589
-
Here we consider that the autowiring enabled for controller classes (the default when using the API Platform distribution).
590
-
This action will be automatically registered as a service (the service name is the same as the class name: `App\Controller\BookSpecial`).
591
-
592
-
API Platform automatically retrieves the appropriate PHP entity then deserializes it, and for `POST` and `PUT` requests
593
-
updates the entity with data provided by the user.
594
-
595
-
If you want to bypass the automatic retrieval of the entity, you can set the parameter `_api_receive` to `false`.
596
-
This way, it will skip the `Read`, `Deserialize` and `Validate` listeners (see [the event system](events.md) for more information).
597
-
598
-
Services (`$myService` here) are automatically injected thanks to the autowiring feature. You can type-hint any service
599
-
you need and it will be autowired too.
600
-
601
-
The `__invoke` method of the action is called when the matching route is hit. It can return either an instance of `Symfony\Component\HttpFoundation\Response`
602
-
(that will be displayed to the client immediately by the Symfony kernel) or, like in this example, an instance of an entity
603
-
mapped as a resource (or a collection of instances for collection operations).
604
-
In this case, the entity will pass through [all built-in event listeners](events.md) of API Platform. It will be
605
-
automatically validated, persisted and serialized in JSON-LD. Then the Symfony kernel will send the resulting document to
606
-
the client.
607
-
608
775
Alternatively, you can also use standard Symfony controller and YAML or XML route declarations. The following example does
609
776
exactly the same thing than the previous example in a more Symfony-like fashion:
610
777
@@ -619,7 +786,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
619
786
620
787
class BookController extends Controller
621
788
{
622
-
public function specialAction(Book $data, MyService $service): object
789
+
public function specialAction(Book $data, MyService $service): Book
0 commit comments