FOSRestBundle icon indicating copy to clipboard operation
FOSRestBundle copied to clipboard

Validation trouble with the ParamConverter for POST

Open kohld-basilicom opened this issue 4 years ago • 2 comments

Hey, community,

Please excuse the issue, but I'm at my wit's end with my knowledge and research.

I have the following problem: A while ago I created a POST request with the ParamConverter and a DTO. This DTO contained the classic Symfony Validation Assets (e.g. NotBlank) with their own error messages. This test was successful and the errors were displayed correctly.

Now I have implemented exactly such a workflow again and it does not work as expected. Instead of the Symfony Validation the ParamConverter now directly includes the attributes and their declarations and therefore does not allow an own validation. Additionally I have the phenomenon that this happens even if validate is disabled in the fos_rest config.

Do you have an idea or an approach where my mistake could lie? For clarification I attach the relevant snippets and information:

FOSRestBundle Version: 2.7.4

Controller Action:

/**
     * @Rest\Post("/test")
     * @ParamConverter("testProductDTO", converter="fos_rest.request_body")
     *
     * @param TestProductDTO $testProductDTO
     * @param ConstraintViolationListInterface $validationErrors
     *
     * @return RestView
     */
    public function createTestProduct(TestProductDTO $testProductDTO, ConstraintViolationListInterface $validationErrors): RestView
    {
        if (\count($validationErrors) > 0) {
            /** @var ConstraintViolationDTO $normalizedValidationErrors */
            $normalizedValidationErrors = $this->constraintViolationListNormalizer->normalize($validationErrors);

            return RestView::create($normalizedValidationErrors, Response::HTTP_BAD_REQUEST);
        }

        $product = $this->testProductService->createTestProduct($testProductDTO);

        return RestView::create($product, Response::HTTP_CREATED);
    }

DTO:

<?php
declare(strict_types=1);

namespace ApiBundle\Model\TestProduct;

use Symfony\Component\Validator\Constraints as Assert;

final class TestProductDTO
{
    /**
     * @var int
     *
     * @Assert\NotBlank
     * @Assert\Type("integer")
     */
    private $id;

    /**
     * @var string
     *
     * @Assert\NotBlank
     * @Assert\Type(
     *     type="string",
     *     message="Custom violation message"
     * )
     *
     */
    private $ean;

    /**
     * TestProduct constructor.
     *
     * @param int $id
     * @param string $ean
     */
    public function __construct(int $id, string $ean)
    {
        $this->id = $id;
        $this->ean = $ean;
    }

    /**
     * @return int
     */
    public function getId(): int
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getEan(): string
    {
        return $this->ean;
    }
}

fos_rest.yml:

fos_rest:
    zone:
        - { path: ^/api/* }
    view:
        view_response_listener:  true
    format_listener:
        rules:
            - { path: ^/api, prefer_extension: true, fallback_format: json, priorities: [ json ] }
    exception:
        exception_controller: 'fos_rest.exception.controller:showAction'
        codes:
            ApiBundle\Exception\EntityNotFoundException: 404
            ApiBundle\Exception\EntityAlreadyExistsException: 422
    body_converter:
        enabled: true
        validate: true
        validation_errors_argument: validationErrors
    param_fetcher_listener: force
    serializer:
        serialize_null: true

Test request body:

{
  "id" : 1212,
  "ean": false
}

Test response:

{
  "code": 400,
  "message": "The type of the \"ean\" attribute for class \"ApiBundle\\Model\\TestProduct\\TestProductDTO\" must be one of \"string\" (\"boolean\" given)."
}

Best regards, Dennes

kohld-basilicom avatar May 15 '20 11:05 kohld-basilicom

I am having same issue.

martinstepanek avatar Jan 30 '21 13:01 martinstepanek

For me helps removing options:

-@ParamConverter("news", converter="fos_rest.request_body", options={"validator"={"groups"={"news:create"}}})
+@ParamConverter("news", converter="fos_rest.request_body")

SergeShkurko avatar Feb 16 '21 09:02 SergeShkurko