0

I have created an API REST Symfony project using FOSRestBundle and I'm having problems with type fields validation when I throw POST action.

It's important to know that this API REST is going to be used from a React Js project, and NOT from a Symfony form.

My controller looks:

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Team;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations as REST;
use FOS\RestBundle\View\View;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationListInterface;

/**
 * Add a Team
 *
 * @param Team $team
 * @param ConstraintViolationListInterface $validationErrors
 * @return Team
 *
 * @REST\Post("/team")
 * @ParamConverter("team", converter="fos_rest.request_body")
 * @REST\View(serializerGroups={"Team"}, statusCode=201);
 */
public function addAction(
    Team $team,
    ConstraintViolationListInterface $validationErrors
) {
    if (count($validationErrors) > 0) {
        $view = new View();
        $view->setStatusCode(400);
        $view->setData($validationErrors);
        return $view;
    }

    $em = $this->getDoctrine()->getManager();
    $em->persist($team);
    $em->flush();

    return $team;
}

My param converter configuration (config.yml file):

# FOSRestBundle Configuration
fos_rest:
    format_listener:
        rules:
            prefer_extension: false
            priorities:
                - json
            fallback_format: json
    view:
        view_response_listener: true
        empty_content: 204
    body_converter:
        enabled: true
        validate: true

And my Entity:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Validator;

/**
 * Team
 *
 * @ORM\Table(name="teams")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\TeamRepository")
 */
class Team
{
     /**
     * @var string team name
     *
     * @ORM\Column(name="name", type="string", length=20)
     *
     * @Serializer\Type("string")
     * @Serializer\Groups({"Team"})
     *
     * @Validator\NotNull(message="Field name is required")
     * @Validator\Type(type="string", message="name field has a wrong type")
     */
    private $name;

    /**
     * @var int team players number
     *
     * @ORM\Column(name="num_players", type="integer")
     *
     * @Serializer\Type("integer")
     * @Serializer\Groups({"Person"})
     *
     * @Validator\NotNull(message="Field num_players is required")
     * @Validator\Type(type="integer", message="num_players field has wrong type")
     */
    private $num_players;

    public function getName()
    {
        return $this->name;
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function getNumPlayers()
    {
        return $this->num_players;
    }

    public function setNumPlayers(int $numPlayers)
    {
        $this->num_players = $numPlayers;
    }
}

Then when I send the following POST action:

{ 
  "name" : "Chelsea FC",
  "num_players" : "sdfkjls"
}

I get status code 201 created and API response:

{ 
  "id" : 1,
  "name" : "Chelsea FC",
  "num_players" : 0
}

Why the Controller method doesn't throws validation type error (statusCode 400) if I'm sending a string value (""sdfkjls"") in an integer type field?

Seems that @Validator\Type(type="integer", ...) "num_players" field annotation doesn't works and I dont know why..

How can I solve this API REST validation problem? Thanks.

Wildchild
  • 233
  • 1
  • 6
  • 17
  • I had a similar issues with annotations and I used `loadValidatorMetadata` method with constraint definition instead. – Lukas Hajdu May 11 '17 at 09:53
  • I have add this function to Entity: `public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('num_players', new Validator\Type( 'integer' )); }` but it doesn't works.. – Wildchild May 11 '17 at 10:38
  • You can try to add an xdebug breakpoint to this method and see if the script is executing it at all. If it's not executed, then there is something wrong with your validation call. Normally you validate with something like `$validator->validate($author)` or `$form->isValid()`, so maybe there is something wrong with you param converter in your controller. – Lukas Hajdu May 11 '17 at 10:51
  • I have put an xdebug breakpoint and the method is called perfectly.. – Wildchild May 11 '17 at 11:05
  • Then I have no idea :) I would debug it step by step to see what's happening on the background. – Lukas Hajdu May 11 '17 at 12:52
  • I have encountered the solution in: http://stackoverflow.com/questions/43868455/symfony-how-to-make-jms-serializer-works-with-strict-types/43940956#43940956 – Wildchild May 12 '17 at 15:09

0 Answers0