Install helper bundles for building APIs

We need some third party bundles before we start working on our API. Our API will use the following bundles:

Third party bundles

FOSRestBundle - Provides tools for quick creation of API-controllers

JMSDiExtraBundle - Enables service definitions and dependecy injections via annotations

JMSSerializerBundle - Allows you to serialize your data into a requested output format such as JSON

NelmioApiDocBundle - Automatically generates documentation for the API

Install the bundles with composer

composer require friendsofsymfony/rest-bundle
composer require jms/di-extra-bundle
composer require jms/serializer-bundle
composer require nelmio/api-doc-bundle

Enable the bundles

app/AppKernel.php
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...
            new FOS\RestBundle\FOSRestBundle(),
            new JMS\SerializerBundle\JMSSerializerBundle(),
            new JMS\DiExtraBundle\JMSDiExtraBundle($this),
            new JMS\AopBundle\JMSAopBundle(),
            new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
        );

        // ...
    }
}

Configure the bundles

app/config/routing.yml
NelmioApiDocBundle:
    resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
    prefix:   /api/doc

// ...

Make sure you add this before the fallback URL. Otherwise the fallback URL will match this route.

app/config/config.yml
// ...

fos_rest:
    view:
        view_response_listener: 'force'
    routing_loader:
        default_format: json

nelmio_api_doc: ~

Add a ViewResponseListener for FosRestBundle

This event listener listens for responses from a FosRestBundle controller. It allows us to return arrays and objects that gets converted to serialized JSON data.

src/AppBundle/EventListener/ViewResponseListener.php
<?php

namespace AppBundle\EventListener;

use FOS\RestBundle\Controller\Annotations\View;
use JMS\DiExtraBundle\Annotation\Observe;
use JMS\DiExtraBundle\Annotation\Service;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;

/**
 * @Service("app.view_response_listener")
 */
class ViewResponseListener
{
    /**
     * @Observe(event="kernel.view", priority=110)
     * {@inheritdoc}
     */
    public function onKernelView(GetResponseForControllerResultEvent $event)
    {
        $request = $event->getRequest();
        $request->getSession()->save();

        if (!$request->attributes->has('_view')) {
            $configuration = new View([]);
            $configuration->setSerializerEnableMaxDepthChecks(true);
            $request->attributes->set('_view', $configuration);
        }
    }
}