Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate data in a custom controler

I created a Entity with a custom contoller:

// api/src/Entity/UserRegistration.php


namespace App\Entity;

use ...

/**
 * UserRegistraion Data
 *
 * @ApiResource(collectionOperations={},itemOperations={"post"={
 *         "method"="POST",
 *         "path"="/register",
 *         "controller"=CreateUser::class}})
 *
 */
class UserRegistration
{
     .....
    /**
     * @var string The E-mail
     *
     * @Assert\NotBlank
     * @Assert\Email(
     *     message = "The email '{{ value }}' is not a valid email.",
     *     checkMX = true
     * )
     */
    public $email;
     .....

And a custom Controller:

// api/src/Controller/CreateUser.php


class CreateUser
{

     .....
    public function __invoke(UserRegistration $data): UserRegistration
    {


        return $data;
    }
}

When I call the controller with wrong data (e.g wrong email-address) I would expect an validation error, but it is not checked.

Is there a way to do this?

like image 389
user3532022 Avatar asked Jan 19 '19 10:01

user3532022


1 Answers

Api Platform does the validation on the result of your controller, to make sure your data persisters will receive the right information. Thus you may get invalid data when entering your controller, and need to perform the validation manually if your action needs a valid object.

The most common approaches are either using a Form, which provides among other things validation, or just the Validator as a standalone component. In your case you - since are using ApiPlatform - the latter would be the better choice as you don't need to render a form back to the user, but instead return an error response.

First you will need to inject the Validator into your Controller:

use ApiPlatform\Core\Bridge\Symfony\Validator\Exception\ValidationException;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class CreateUser
{
    private $validator;

    public function __construct(ValidatorInterface $validator)
    {
        $this->validator = $validator;
    }

    public function __invoke(UserRegistration $data): UserRegistration
    {
        $errors = $this->validator->validate($data);
        if (count($errors) > 0) {
            throw new ValidationException($errors);
        }

        return $data;
    } 
}

You can also check how ApiPlatform does it by looking at the ValidateListener. It provides some additional features, e.g. for validation groups, which you don't seem to need at this point, but might be interesting later. ApiPlatform will then use its ValidationExceptionListener to react on the Exception you throw and render it appropriately.

like image 183
dbrumann Avatar answered Sep 21 '22 12:09

dbrumann