Tutos & Astuces

FOSRestBundle + JMSSerializer : Utiliser le format YAML

Vous voulez faire une superbe api mais vous trouvez que l’XML et le JSON c’est trop has-been ? Que vous valez mieux que ça ? Vous trouvez que le YAML c’est...

Vous voulez faire une superbe api mais vous trouvez que l’XML et le JSON c’est trop has-been ? Que vous valez mieux que ça ? Vous trouvez que le YAML c’est trop la classe et que toutes les apis devraient fonctionner de cette manière ? Cet article est fait pour vous ! 😀

Trêve de troll, plus sérieusement il est parfois possible d’avoir besoin de renvoyer du format YAML en api pour certaines applications comme puppet qui l’utilise pour ses configs.

En cherchant un peu, il est assez simple d’implémenter ce format avec FOSRestBundle, JMSSerializerBundle et un peu de bricolage sur Symfony2.

Si vous ne connaissez pas ces bundles, je vous conseille de jeter un œil sur les docs de ceux-ci avant de continuer. 😉

Déclaration du format YAML

Le format YAML (fichiers .yml) n’est pas un format reconnu par défaut sur Symfony. On peut facilement l’implémenter avec l’aide d’un RequestListener comme indiqué dans la doc officielle.

Donc en reprenant leur exemple pour notre format, on obtient ceci:

// src/Acme/DemoBundle/RequestListener.php
namespace Acme\DemoBundle;

use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class RequestListener
{
    public function onKernelRequest(GetResponseEvent $event)
    {
        $event->getRequest()->setFormat('yml', 'text/yaml');
    }
}

N’oubliez pas ensuite de le déclarer en tant que service !

Note : Le type MIME du format YAML n’a pas l’air d’exister officiellement et il est assez discutable. Personnellement, text/yaml fonctionne très bien pour moi…

Configuration de FOSRestBundle

FOSRestBundle utilise JMSSerializer comme serializer par defaut et celui-ci gère sans soucis le format YAML.

Super ! 😀 Il n’y a plus qu’à activer le format dans la config de FOSRest :

# app/config/config.yml
fos_rest:
    routing_loader:
        default_format: json
    view:
        formats:
            xml:  false
            json: true
            rss:  false
            yml:  true

Renvoyer les données avec un Controller

Voila tout est prêt, il n’y a plus qu’à tester ! 🙂

Voici un exemple d’un bête controlleur renvoyant plusieurs données en dur :

// src/Acme/DemoBundle/Controller/TestController.php
namespace Acme\DemoBundle\Controller;

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Routing\ClassResourceInterface;

class TestController extends FOSRestController implements ClassResourceInterface
{
    public function getAction()
    {
        $data = array(
            'text'          => 'lol',
            'assoc_array'   => array(
                'text'          => 'truc',
                'number'        => 42,
                'float'         => 42.24,
                'empty'         => '',
            ),
            'number'        => 1,
            'simple_array'  => array('lol', 'kikou', 'j\'aime les espaces !'),
        );

        $view = $this->view($data);

        return $this->handleView($view, 200);
    }
}

Note : Pour l’url, j’utilise le système de génération automatique des routes de FOSRestBundle, détaillé ici.

Disons que l’url de cette action est /api/test.{_format}, remplaçons _format par yml dans notre navigateur, nous devrions avoir ce résultat:

text: lol
assoc_array:
    text: truc
    number: 42
    float: 42.24
    empty: ''
number: 1
simple_array:
    - lol
    - kikou
    - 'j''aime les espaces !'

Conclusion

Et voilà vous avez fini ! Simple non ? 🙂 Maintenant vous pouvez gérer les formats json, xml, rss et yaml sans soucis.

Si vous souhaitez incorporer un autre format, là il va falloir trouver un autre serializer ou gérer vos propres templates

Si vous avez des améliorations à apporter dans cet article, n’hésitez pas ! 😉

Ce tutoriel à été réalisé avec les versions suivantes :

  • Symfony 2.2.*
  • FOSRestBundle 0.10.*
  • JMSSerializerBundle >=0.9,<=0.10
Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0
  • Ghali Ahmed

    Salut et merci pour l’astuce,

    et si on veut que le format yml soit par defaut

    (sans rajouter le.yml à la fin de l’uri)

    • Soullivaneuh

      Bonjour,

      Je n’ai jamais essayé mais avec `default_format: yaml` peut-être ?