2016-09-29 1 views
1

J'essaie de créer un service Web de repos en utilisant Symfony 3 et FOSRestBundle. Je viens d'un fond Spring + Jackson donc j'essaie de faire en sorte que vous puissiez passer des objets aux contrôleurs en tant que corps de requête qui deviennent des paramètres de fonction et retournent des objets qui sont sérialisés en json, jusqu'ici j'ai réussi à le faire fonctionner pour tout sauf pour les tableaux.
Ceci est mon code:Sérialiser le corps de la requête POST dans le tableau avec FOSRestBundle

configuration

:

#FOSRestBundle 
fos_rest: 
    param_fetcher_listener: true 
    body_listener: 
     enabled: true 
     decoders: 
      json: fos_rest.decoder.json 
    format_listener: 
     rules: 
      - { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true } 

    body_converter: 
     enabled: true 
     #validate: true 

    view: 
     mime_types: 
      json: ['application/json', 'application/json;version=1.0', 'application/json;version=1.1'] 
     view_response_listener: 'force' 
     formats: 
      xml: false 
      json: true 
     templating_formats: 
      html: true 

    exception: 
     codes: 
      'Symfony\Component\Routing\Exception\ResourceNotFoundException': 404 
      'Doctrine\ORM\OptimisticLockException': HTTP_CONFLICT 
     messages: 
      'Symfony\Component\Routing\Exception\ResourceNotFoundException': true 
    allowed_methods_listener: true 
    access_denied_listener: 
     json: true 

C'est le contrôleur

<?php 

namespace AppBundle\Controller; 

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\Request; 
use JMS\DiExtraBundle\Annotation\Inject; 
use FOS\RestBundle\Controller\Annotations\Post; 
use FOS\RestBundle\Controller\Annotations\View; 
use FOS\RestBundle\Controller\FOSRestController; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; 

class DefaultController extends FOSRestController { 

    /** 
    * @Post("/rest", name="rest_test") 
    * @ParamConverter("myArr", converter="fos_rest.request_body") 
    * @View 
    * @param Request $request 
    */ 
    public function restAction(Request $request, array $myArr) { 
     return $myArr; 
    } 
} 

Quand je tente d'appeler cela de mon client de repos (mettre [1, 2] comme corps de la demande) je reçois cette erreur:

{ 
    "code": 500, 
    "message": "Converter 'fos_rest.request_body' does not support conversion of parameter 'myArr'." 
} 

Si je transforme en un objet (c'est-à-dire je change son type de array en MyObject, contenant la variable numbermyVar) et envoie des données qui reflètent cette structure d'objet (comme {"myVar": 2}) cela fonctionne très bien, mais il ne fonctionne pas avec un tableau .

Répondre

2

Après des jours de jeu avec le code et cette conversation avec l'un des collaborateurs de FoS https://github.com/FriendsOfSymfony/FOSRestBundle/issues/1582 J'ai découvert que, si vous utilisez le bundle JMS Serializer (ce que je pense que tout le monde a), vous pouvez écrire array dans le champ de classe du convertisseur de paramètres et le désérialiser dans un tableau. Je l'ai essayé plus tôt, je suppose

@ParamConverter("myarr", class="array", converter="fos_rest.request_body") 

Il peut même désérialiser les tableaux d'objets (tant qu'ils sont de la même classe, je suppose)

@ParamConverter("myarr", class="array<Namespace/Class>", converter="fos_rest.request_body") 
1

Le but du convertisseur de corps FOS Rest est de peupler des objets et non des tableaux. Vous pouvez essayer d'implémenter votre propre convertisseur de paramètres (see this documentation), mais je ne suis vraiment pas sûr que vous puissiez réaliser ce que vous voulez.

De toute façon, traiter des objets ne serait pas plus propre? Cela vous permettra d'être sûr que les données que vous recevez correspondent à ce que vous attendez, d'utiliser des validations, etc. ...

+0

Je peux toujours créer un objet avec un tableau intérieur je suppose (n'ai pas encore essayé). Mais il y a des situations dans lesquelles je dois envoyer, par exemple, un tableau d'identifiants pour dire au backend de faire des opérations sur un ensemble d'éléments. – valepu

+0

Peut-être que c'est votre conception REST qui n'est pas correcte alors? REST n'est pas vraiment conçu pour effectuer des opérations sur plusieurs ressources avec une seule requête. Si vous avez vraiment besoin de le faire, je pense que vous devrez le faire manuellement, car FOS REST n'est pas conçu pour cela. :/ – Boulzy

+0

La documentation de fosrestbundle indique même que vous pouvez utiliser la méthode générée automatiquement PATCH (pas encore essayé) pour mettre à jour partiellement un sous-ensemble de ressources http://symfony.com/doc/current/bundles/FOSRestBundle/5-automatic -route-generation_single-restful-controller.html, c'était juste un exemple ... Je suis assez confiant qu'il y a beaucoup de cas d'utilisation où vous pourriez avoir besoin de sen un tableau dans un appel REST. En outre, Spring + Jackson vous permet d'envoyer un tableau (de n'importe quel type) en tant que corps de requête – valepu