How to return or display JSON data using FOSRestBundle

I am working in Restful API using Symfony2 and FOSRestBundle. I have read the layer view docs but it is not clear to me how to handle the output for the API. What I want to achieve is simple: display or return or output the result as valid JSON. This is what I have the controller:

<?php

/**
 * RestAPI:       Company.
 */
namespace PDI\PDOneBundle\Controller\Rest;

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\Annotations\Get;

class CompanyRestController extends FOSRestController
{
    /**
     * Gets all companies.
     *
     * @return array
     *
     * @ApiDoc(
     *   resource = true,
     *       https = true,
     *   description = "Gets all companies",
     *   statusCodes = {
     *      200 = "Returned when successful",
     *      400 = "Returned when errors"
     *   }
     * )
     * @Get("/api/v1/companies")
     *
     */
    public function getCompaniesAction()
    {
        $response = array();
        $em = $this->getDoctrine()->getManager();
        $entities = $em->getRepository('PDOneBundle:Company')->findAll();

        if ($entities) {
            foreach ($entities as $entity) {
                $response['companies'][] = [
                    'id' => $entity->getId(),
                    'createdAt' => $entity->getCreatedAt(),
                    'updatedAt' => $entity->getUpdatedAt(),
                    'name' => $entity->getName(),
                    'logo_url' => $entity->getLogoUrl(),
                    'division' => $entity->getDivision(),
                    'inactive' => $entity->getInactive(),
                ];
            }

            $response['status'] = 'ok';
        } else {
            $response['status'] = 'error';
        }

        return $response;
    }
}

      

If I try this url: /app_dev.php/api/v1/companies.json

I have a 404 error:

{"code":404,"message":"No route found for \"GET\/api\/v1\/companies.json\""}

      

If I try this url: the https://reptool.dev/app_dev.php/api/v1/companies

error is included:

Unable to find template ". 500 - Internal Server Error - InvalidArgumentException 3 Related Exceptions: Twig_Error_Loader" InvalidArgumentException "InvalidArgumentException"

I also check FOSRestBundleByExample but didn't get much help.

What am I missing here? How can I achieve what I need? Any advice?

FOSRest Config

I forgot to add the FOSRestBundle to config.yml

:

#FOSRestBundle
fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener:
        rules:
            - { path: ^/, priorities: [ json, html ], fallback_format: ~, prefer_extension: true }
        media_type:
            version_regex: '/(v|version)=(?P<version>[0-9\.]+)/'

    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

      

+3


source to share


1 answer


I can feel your pain. I also started getting into trouble. One important place to start is config. Here is what I am using in my implementation.

fos_rest:
    param_fetcher_listener: 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
    format_listener:
        rules:
            - { path: ^/, priorities: [ json, html ], fallback_format: ~, prefer_extension: true }
        media_type:
            version_regex: '/(v|version)=(?P<version>[0-9\.]+)/'
    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
    body_listener: true

      

Q format_listener

, if you want JSON to be the default response, make sure it comes first in the priorities. Otherwise, your title will have to include Accept: application/json

every time. This is probably because you are getting a twig error when you try to use a branch to output HTML output.

Also, make sure you have a serializer like http://jmsyst.com/bundles/JMSSerializerBundle installed and included with your AppKernal.



In your controller, I found that it is easiest to extend the FOSRestController like you do, but also return the view object instead of creating the array yourself. The serializer will handle all of this for you.

/**
 * RestAPI:       Company.
 */
namespace PDI\PDOneBundle\Controller\Rest;

use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\Annotations\Get;

class CompanyRestController extends FOSRestController
{
    /**
     * Gets all companies.
     *
     * @return array
     *
     * @ApiDoc(
     *   resource = true,
     *       https = true,
     *   description = "Gets all companies",
     *   statusCodes = {
     *      200 = "Returned when successful",
     *      400 = "Returned when errors"
     *   }
     * )
     * @Get("/api/v1/companies")
     *
     */
    public function getCompaniesAction()
    {
        $response = array();
        $em = $this->getDoctrine()->getManager();
        $entities = $em->getRepository('PDOneBundle:Company')->findAll();
        if(!$entities)
        {
             return $this->view(null, 400);
        }

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

      

Hope this helps a little.

+3


source







All Articles