Search code examples
phpsymfonysymfony4api-platform.com

What is called after a Data Persister on Api-Platform?


I'm working with Api-Platform 2.5 and Symfony 4.4 (lts).

I have discovered the API Platform and I understand that there are many "interceptors" that intercept the HTTP requests:

for GET requests: The Data Provider, The Controller, The Serialization Process and finally an "anonymous process" that's setting the response code.

for POST, PUT, PATCH, and DELETE: The serialization process, The Data Provider, The Controller, The Data Persister and finally the "anonymous process" that's setting the response code.

Here I have my Data Persister:

ProductDataPersister:

namespace App\DataPersister;

use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use App\Entity\Product;

final class ProductDataPersister implements ContextAwareDataPersisterInterface
{
    public function supports($data, array $context = []): bool
    {
        return $data instanceof Product;
    }

    public function persist($data, array $context = [])
    {
        //dd('persist');
        return $data;
    }

    public function remove($data, array $context = [])
    {
        //dd('remove');
    }
}

In this case neither persist nor remove are making the database stuff because it has to be done manually by injecting entity manager etc.

My question is, as we say the remove action with this code never deletes a Product and that's what I want But the response I get to the DELETE request still not overridden and still returns a 204 status code (no content).

I want to override the response type. What other listener gets executed after the Data Persister?

Is it overridable?


Solution

  • If you take a look at Api-Platform event system, it is clear that the event you are looking for, the one you refer as "anonymous process", is the appropriately named RespondListener.

    You can see here the exact point where it is setting the response code.

    The simplest way to override this would be to register your own event listener/subscriber to be executed after this listener:

    public static function getSubscribedEvents()
        {
            return [
                KernelEvents::VIEW => ['fooMethod', EventPriorities::POST_RESPOND],
            ];
        }
    

    On fooMethod(ViewEvent $event) you can access the access response object ($event->getResponse() and modify it, or even create your own response object (although that's likely to be even less optimal).


    Alternatively, you could decorate the @api_platform.listener.view.respond service, and implement your overriding logic in the decorator.