api-platform icon indicating copy to clipboard operation
api-platform copied to clipboard

Data Persisted on PUT Request despite Validation Violations

Open lotfiGipsyKing opened this issue 1 year ago • 2 comments

API Platform version(s) affected: 3.3.12

Description

I encountered an issue where, during a PUT request, the data is being persisted even when validation constraints are violated. This behavior is inconsistent with the POST request, where the data is not persisted if validation violations occur

How to reproduce

  1. Create a custom validator that adds violations when specific rules are not respected.
<?php

declare(strict_types=1);

namespace App\Validator;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class UniqueRoleInValidator extends ConstraintValidator
{

    public function __construct() {}

    /**
     * @param MyEntiy  $value
     * @param MyContraint $constraint
     */
    public function validate($value, Constraint $constraint): void
    {
        $this->context->buildViolation($constraint->message)
            ->addViolation();
    }
}
  1. Use this validator in an entity.

  2. Perform a POST request with invalid data: Result: Validation violation is returned with HTTP status code 422, and the data is not persisted (expected behavior).

image

  1. Perform a PUT request with invalid data: Result: Validation violation is returned with HTTP status code 422, but the data is persisted (unexpected behavior).

image

Possible Solution

Additional Context

This is my ressources définition:

#[ORM\Entity(repositoryClass: MyEntityRepository::class)]
#[ApiResource(
    operations: [
        new GetCollection(security: "is_granted('ROLE_USER')"),
        new Get(security: "is_granted('ROLE_ADMIN')"),
        new Post(security: "is_granted('ROLE_ADMIN')"),
        new Put(security: "is_granted('ROLE_ADMIN')"),
        new Patch(security: "is_granted('ROLE_ADMIN')"),
    ],
    normalizationContext: ['groups' => MyEntity::SERIALIZATION_GROUP_READ],
)]

lotfiGipsyKing avatar Oct 07 '24 10:10 lotfiGipsyKing

@lotfiGipsyKing Have you found a solution to your issue? I currently experience something similar, where a PATCH request would (correctly) return a 403 (based on a Voter decision), but the changes where still persisted.

biertz avatar Jan 02 '25 08:01 biertz

hello @biertz, I managed to fix the issue, i had a kernel request listener with a high priority (priority: 1) that included a call to $entityManager->flush(). This caused the data to be persisted to the database regardless of whether validation constraints were violated because the flush occurred before validation was fully processed.

#[AsEventListener(event: KernelEvents::REQUEST, method: 'onKernelRequest', priority: 1)]

so if you have the same issue, check if you don't a flush in your code that occur before the validation

lotfiGipsyKing avatar Jan 02 '25 09:01 lotfiGipsyKing