question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Validation on DELETE action

See original GitHub issue

It looks like validation on DELETE action has been explicitly prevented in ValidateListener::onKernelView()

//src\Validator\EventListener\ValidateListener.php::onKernelView()
        if (   
            $controllerResult instanceof Response   
            || $request->isMethodSafe()   
            || $request->isMethod('DELETE')  //<========================== here, why so much hate?   
            || !($attributes = RequestAttributesExtractor::extractAttributes($request))   
            || !$attributes['receive']   
            || $this->isOperationAttributeDisabled($attributes, self::OPERATION_ATTRIBUTE_KEY)   
        ) {   
            return;   
        }

However validation is very useful to enforce some business logic on the action itself (and share its behavior with the regular controller form view and the api platform). Would it be possible to let validation occurs on DELETE action? Alternatively add a parameter to enable it?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:2
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
benblubcommented, Jun 16, 2021

The current recommendation would be to use DataPersister https://api-platform.com/docs/core/data-persisters/

    use ApiPlatform\Core\Validator\ValidatorInterface;

    // ...

    /**
     * @param mixed $data
     */
    public function remove($data, array $context = []): void
    {
        /** @var User $data */
        $this->validator->validate($data, ['groups' => 'Delete']);

        $this->em->remove($data);
        $this->em->flush();
    }
1reaction
CedricYiicommented, Jun 7, 2021

Thanks for sharing your workaround. It’s working great, however it means duplicating this code for every delete actions. We tried to solve this hard-coded behavior by reversing it in an event subscriber:

<?php
//src\EventSubscriber\DeleteValidationSubscriber.php

namespace App\EventSubscriber;

use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
use ApiPlatform\Core\Validator\ValidatorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class DeleteValidationSubscriber implements EventSubscriberInterface
{
    private $validator;
    private $resourceMetadataFactory;

    /**
     * @param ValidatorInterface $validator
     * @param ResourceMetadataFactoryInterface $resourceMetadataFactory
     */
    public function __construct(ValidatorInterface $validator, ResourceMetadataFactoryInterface $resourceMetadataFactory)
    {
        $this->validator = $validator;
        $this->resourceMetadataFactory = $resourceMetadataFactory;
    }

    /**
     * Validates data returned by the controller for DELETE action because api-platform is ignoring it
     *
     * @param ViewEvent $event
     * @throws ResourceClassNotFoundException
     */
    public function onKernelView(ViewEvent $event)
    {
        $controllerResult = $event->getControllerResult();
        $request = $event->getRequest();

        if (
            $controllerResult instanceof Response
            || !$request->isMethod('DELETE')
            || $request->isMethodSafe()
            || !($attributes = RequestAttributesExtractor::extractAttributes($request))
            || !$attributes['receive']
        ) {
            return;
        }

        $resourceMetadata = $this->resourceMetadataFactory->create($attributes['resource_class']);

        $validationGroups = $resourceMetadata->getOperationAttribute($attributes, 'validation_groups', null, true);
        if (!is_null($validationGroups)) {
            $this->validator->validate($controllerResult, ['groups' => $validationGroups]);
        }
    }

    /**
     * @return array|string[]
     */
    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::VIEW => ['onKernelView', 64],
        ];
    }
}

With that in place, validation is working as expected whenever “validation_groups” is explicitly defined on the “delete” item operation without other extra code. Does it make sense?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Validation Rule On Delete - Salesforce Developer Community
Just want to know that is there any way to fire validation rule on any record delete (Only on delete). I don't want...
Read more >
Api-Platform: use validation_groups on DELETE action
Here is the solution we used to solve this hard-coded behavior in ApiPlatform by reversing it in an event subscriber:
Read more >
Validation rule on delete action button in Datagrid
I would like to created validation rule on the delete action button. It cannot delete data in the grid if the selected date...
Read more >
Understand validations on record deletion | Zoho Creator Help
The Validations on record deletion action will executed when you try to delete a record in the form.
Read more >
Validation-OnDelete Not Getting Trigerred When Clicking on ...
The Validation-OnDelete event runs in the Buffer, it's not trigerred until a Save action get trigerred. When you click on the Trash button,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found