Erreur tuto api rest avec Symfony 3

Les groupes avec le sérializer

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

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

+0 -0

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.

Auteur du sujet

Bonne remarque mais ça ne change rien. J’arrive vraiment pas à comprendre d’ou vient le problème. Je suis repassé plusieurs fois sur le code, il y a un truc qui m’échappe.

+0 -0

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).

Auteur du sujet

Ah désolé j’ai complètement oublié de push cette partie (j’ai pas l’habitude de push quelque chose qui ne fonctionne pas :) ) Je push dés que je peux, je te dis quand c’est fait.

+0 -0
Auteur du sujet

Désolé j’ai dû arreter le tuto pendant 2 semaines par manque de temps et j’ai complètement oublié de pusher le code qui pause problème. Voici mon code, je n’ai toujours pas compris la cause du problème -> mon code

+0 -0

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.

Édité par BestCoder

Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

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