Erreur tuto api rest avec Symfony 3

Les groupes avec le sérializer

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Je suis bloqué dans le tuto api Rest avec Symfony (qui est très bien au passage :) ), au chapitre les groupes avec le sérializer: https://zestedesavoir.com/tutoriels/1280/creez-une-api-rest-avec-symfony-3/developpement-de-lapi-rest/relations-entre-ressources/#2-les-groupes-avec-le-serialiseur-de-symfony

je pense avoir bien suivi les différentes étapes et j’arrive à cette erreur :

1
{"code":400,"message":"Validation Failed","errors":{"errors":["This value should not be blank.","This value should not be blank.","This form should not contain extra fields."]}}

je ne vois pas le problème puisque les données que j’envoie en POST ne sont pas vide:

1
2
3
4
{
    "type": "less_than_12",
    "value": 5.75
}

Je pense que mon erreur est vraiment bête mais j’arrive pas à mettre la main dessus, j’aurai donc besoin d’un œil nouveau pour m’aider.

Mon controller Price:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    <?php

namespace AppBundle\Controller\Place;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use FOS\RestBundle\Controller\Annotations as Rest;
use AppBundle\Entity\Price;
use AppBundle\Form\Type\PriceType;

class PriceController extends Controller {

    /**
    * @Rest\View(serializerGroups={"price"})
    * @Rest\Get("/places/{id}/prices")
    */
    public function getPricesAction(Request $request){

        $em = $this->getDoctrine()->getManager();

        $place = $em->getRepository('AppBundle:Place')->find($request->get('id'));
        if(empty($place)){
            return $this->placeNotFound();
        }

        return $place->getPrices();
    }

    /**
    * @Rest\View(statusCode=Response::HTTP_CREATED, serializerGroups={"price"})
    * @Rest\Post("/places/{id}/prices")
    */
    public function postPricesAction(Request $request){

        $em = $this->getDoctrine()->getManager();

        $place = $em->getRepository('AppBundle:Place')->find($request->get('id'));
        if(empty($place)){
            return $this->placeNotFound();
        }

        $price = new Price();
        $price->setPlace($place);
        $form = $this->createForm(PriceType::class, $price);
        $form->submit($request->request->all());

        if($form->IsValid()){
            $em->persist($price);
            $em->flush();
            return $price;
        } else {
            return $form;
        }
    }

    private function placeNotFound(){

        return \FOS\RestBundle\View\View::create(['message' => 'Place not found'], Response::HTTP_NOT_FOUND);
    }
}

L’entity price:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Price
 *
 * @ORM\Table(name="prices",
 * uniqueConstraints={@ORM\UniqueConstraint(name="prices_type_place_unique",columns={"type", "place_id"})})
 * @ORM\Entity(repositoryClass="AppBundle\Repository\PriceRepository")
 */
class Price
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="type", type="string", length=255)
     * @Assert\Choice(callback = {"less_than_12", "for_all"})
     * @Assert\NotBlank()
     */
    private $type;

    /**
     * @var float
     *
     * @ORM\Column(name="value", type="float")
     * @Assert\NotBlank()
     */
    private $value;

    /**
    * @ORM\ManyToOne(targetEntity="Place", inversedBy="prices", cascade={"persist"})
    * @var Place
    */
    private $place;

    // Les accesseurs ....
}

L’entity place:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;

/**
* @ORM\Entity()
* @ORM\Table(name="places", 
* uniqueConstraints={@ORM\UniqueConstraint(name="places_name_unique",columns={"name"})})
*/
class Place {

    /**
    * @ORM\Id
    * @ORM\Column(type="integer")
    * @ORM\GeneratedValue
    */
    protected $id;

    /**
    * @ORM\Column(type="string")
    * @Assert\NotBlank()
    */
    protected $name;

    /**
    * @ORM\Column(type="string")
    * @Assert\NotBlank()
    */
    protected $address;

    /**
    * @ORM\OneToMany(targetEntity="Price", mappedBy="place")
    * @var Price[]
    */
    private $prices;

    public function __construct(){

        $this->prices = new ArrayCollection();
    }
    //Les accesseurs
}   

Et mon formulaire :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PriceType extends AbstractType {

    public function builfForm(FormBuilderInterface $builder, array $options){

        $builder->add('type');
        $builder->add('value');
    }

    public function configureOptions(OptionsResolver $resolver){

        $resolver->setDefaults([
            'data_class' => 'AppBundle\Entity\Price',
            'csrf_protection' => false
        ]);
    }
}

Je peux fournir d’autres morceaux de code si besoin. Merci

Le endpoint c’est l’url que tu utilises pour envoyer le payload (les données en json dans ta requête).

Par exemple si tu fais une requête POST sur l’url http://rest-api.local/prices. L’url http://rest-api.local/prices est aussi appelée endpoint.

Si tu peux publier tout ton code sur github, ça sera plus simple de t’aider. Si je regarde le message d’erreur, j’ai vraiment l’impression que tu postes sur le mauvais endpoint.

Tu peux poster la requête curl que tu effectues (si tu utilises Postman, tu peux exporter la requête curl associée).

Salut,

Dans ton code https://github.com/DrManhattan93/testapi/blob/master/src/AppBundle/Form/Type/PriceType.php#L11 c’est écrit builfForm au lieu de buildForm.

Du coup, ton formulaire ne contient aucun élément et renvoie un objet price toujours vide.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte