skip to Main Content

Here is my simplified class of my DTO which is filled by the Serializer:

<?php

namespace AppApiDto;

use OpenApiAttributes as OA;
use SymfonyComponentSerializerAnnotationGroups as SerializerGroups;
use SymfonyComponentValidatorConstraints as Assert;


#[OASchema()]
readonly class WorkHour implements DtoInterface
{
    public function __construct(
        #[OAProperty(description: 'House name', type: 'string')]
        #[AssertLength(
            exactly: 4,
            exactMessage: 'House name is mandatory. Stringlength 4',
            groups: ['create', 'update']
        )]
        #[SerializerGroups(['view', 'create', 'update', 'collection'])]
        public string $sapHouseNumber
        ) {
    }
}

I am writing unit tests and try to fail the validation by sending an empty string for this value with creation. But the json is serialized and my DTO is created without any complaint.

Is the Assert correct? Should it work?

If yes, I have to search for the error elsewhere in my code.
What am I missing? Why is my validation not working?

It looks like the class Length is used, but not the class LengthValidator.

2

Answers


  1. Well I don’t know your usecase, but in your question you mention "serializing". If you serialize a DTO into JSON, the symfony serializer does not any kind of validation, since it is not its responsibility. The validation itself is performed by the Validator component and it can be manually invoked (see this).

    If your usecase is validating a JSON request that you get to an endpoint and then deserializing this request into a DTO, it would be helpful if you shared a Controller, where you are doing this deserialization. Since Symfony 6.3 there is an attribute #[MapRequestPayload] (see this) that tells the framework to validate (and return 422 by default, if there are any invalid data against constraints), and you should get fully validated and populated DTO.

    Beware that validating null is in fact not a responsibility of Length constraint, but it is validated either by NotNull or NotBlank constraint.

    So please, improve a bit on your question, clarify the use case and provide additional info about your framework version (6.0 / 6.1 / 6.2 ….).

    Login or Signup to reply.
  2. I think the Length constraint doesn’t have an exact option. Instead, you should use the min and max options if you want to enforce an exact length. You have to update your DTO class to use min and max options like following

    public function __construct(
            #[OAProperty(description: 'House name', type: 'string')]
            #[AssertLength(
                **min: 4,
                max: 4,
                minMessage: 'House name must be exactly 4 characters long.',
                maxMessage: 'House name must be exactly 4 characters long.',**
                groups: ['create', 'update']
            )]
            #[SerializerGroups(['view', 'create', 'update', 'collection'])]
            public string $sapHouseNumber
        )
    

    As well as be sure that you are triggering the validation manually in your unit test.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search