3
votes

An API has been created to allow Posts to be created with a description and any number of attached Photos.

The problem was that when an API request to edit a Post was received with a null description the typehint would fail.

 class Post {

 /**
  * @Assert\NotBlank 
  * @ORM\Column(type="text")
  */
 private $description;

 /**
  * @ORM\ManyToMany(targetEntity="App\Entity\Photo")
  */
 private $photos;

 public function setDescription(string $descripton)

Which means instead of the Symfony validation failing Assert\NotBlank it was returning a 500.

This could have been fixed by allowing nulls in the method ?string, this would allow the validation to be called, but result in a dirty entity.

The DTO (Data Transfer Object) approach, a new class to represent the data was created and the validation rules applied to this, this was then added to the form.

class PostData {

 /**
  * @Assert\NotBlank 
  */
 public $description;

 /**
  * @Assert\Valid
  * @var Photo[]
  */
 public $photos;

The form has was modified:

class PostType extends AbstractType {

public function buildForm(FormBuilderInterface $builder, array $options)
    $builder
        ->add('description')
        ->add('photos', EntityType::class, [
        'class' => Photo::class,
        'multiple' => true,
    ]);
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => PostData::class,
    ));
}

This worked for description it could be validated without changing the Post entity. If a null was received PostData would trigger the Assert\NotBlank and Post::setDescription would not be called with null.

The problem came when trying to validate Photos existed, if the photo existed it would work, if it didn't there would be a 500 error.

Potentially meaningless 500 error which doesn't indicate the reason

Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is not supported. (500 Internal Server Error)

How can I use DTO PostData to validate a Photo entity exists?

1

1 Answers

0
votes

Update composer.json and run composer update

       "symfony/http-foundation": "4.4.*",

The issue is related to https://github.com/symfony/symfony/issues/27339

This will give a more meaningful Symfony Form error

Unable to reverse value for property path \"photos\": Could not find all matching choices for the given values

It will also return a lot of extra information if you serilize form errors including DATABASE_URL and APP_SECRET.

I do not recommend running this in production.