Unable to find template when returning response with FOSRestBundle
Asked Answered
M

3

3

I'm using FOS Rest Bundle to build an Api, the problem is that every time I try to return anything I get the error message: "Unable to find template" I don't really want to render a template, but to serialize an entity that I have.

Here is my code:

routing.yml:

acme_api_register:
    pattern: /user
    defaults: { _controller: AcmeApiBundle:User:post, _format: json }
    requirements:
          _method: POST

controller.php:

<?php

namespace Acme\ApiBundle\Controller;

use Acme\ApiBundle\Entity\Patient;
use Acme\ApiBundle\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use FOS\RestBundle\Controller\Annotations\View;

//use FOS\RestBundle\View\View;

    class UserController extends Controller
    {
        /**
         * @View()
         */
        public function postAction()
        {
            $user = new Patient();

            $user->setName("Daniel");
            $user->setLastName("My lastName");
            $user->setEmail("[email protected]");

            return $user;
        }
    }

and my app/config.yml

sensio_framework_extra:
    view: { annotations: false}
    router: { annotations: true }

fos_rest:
    format_listener:
        rules:
            - prefer_extension: false
    routing_loader:
        default_format: json
    view:
        view_response_listener: force

I would appreciate any help a lot!

PD:

composer.json:

{
    "name": "symfony/framework-standard-edition",
    "license": "MIT",
    "type": "project",
    "description": "The \"Symfony Standard Edition\" distribution",
    "autoload": {
        "psr-0": { "": "src/" }
    },
    "require": {
        "php": ">=5.3.3",
        "symfony/symfony": "~2.4",
        "doctrine/orm": "~2.2,>=2.2.3",
        "doctrine/doctrine-bundle": "~1.2",
        "twig/extensions": "~1.0",
        "symfony/assetic-bundle": "~2.3",
        "symfony/swiftmailer-bundle": "~2.3",
        "symfony/monolog-bundle": "~2.4",
        "sensio/distribution-bundle": "~2.3",
        "sensio/framework-extra-bundle": "~3.0",
        "sensio/generator-bundle": "~2.3",
        "incenteev/composer-parameter-handler": "~2.0",
        "friendsofsymfony/rest-bundle": "1.1.*",
        "jms/serializer-bundle": "0.13.*"
    },
    "scripts": {
        "post-install-cmd": [
            "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
        ],
        "post-update-cmd": [
            "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
        ]
    },
    "config": {
        "bin-dir": "bin"
    },
    "extra": {
        "symfony-app-dir": "app",
        "symfony-web-dir": "web",
        "symfony-assets-install": "symlink",
        "incenteev-parameters": {
            "file": "app/config/parameters.yml"
        },
        "branch-alias": {
            "dev-master": "2.4-dev"
        }
    }
}
Marvel answered 26/2, 2014 at 22:17 Comment(1)
possible duplicate of FOS rest bundle: unable to find templateJonathanjonathon
J
4

This happens because you're probably using a browser to test your API. If you open your console inspector you'll see what's the request your browser is sending to your API. As you can see the Accept header looks something like:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

As you can see the first accepted format is text/html. That's why I guess your application is trying to return an HTML response, but it can't find the template!

So I suggest you disable the html format if you don't need it and set json as the default format.

fos_rest:
    param_fetcher_listener: true
    format_listener:
        rules:
            fallback_format: json
            prefer_extension: false
            priorities: [json, xml]
    view:
        view_response_listener: force
        formats:
            json: true
            xml: true
            jsonp: false
            rss: false
            html: false
        failed_validation: HTTP_BAD_REQUEST

With such configuration you're saying that the only formats you support are json and xml and, if none is specified, use json. Now open your browser again and you'll get your resource as an XML. That's because the Accept header is still Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8. Your browser doesn't know you're calling a Rest API and what's your preferred format :-)

To test your API I suggest you use a proper client. If you're using Chrome then take a look at the Advanced REST client extension.

Jonathanjonathon answered 25/9, 2015 at 10:14 Comment(0)
D
2

I think you are using the wrong controller, try using the FOSRestController instead. Your controller code should be something like this.

<?php

    namespace Acme\ApiBundle\Controller;

    use Acme\ApiBundle\Entity\Patient;
    use Acme\ApiBundle\Entity\User;
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\Response;
    use FOS\RestBundle\Controller\Annotations\View;
    use FOS\RestBundle\Controller\FOSRestController;


    class UserController extends FOSRestController
    {
        /**
         * @View()
         */
        public function postUserAction()
        {
            $user = new Patient();

            $user->setName("Daniel");
            $user->setLastName("My lastName");
            $user->setEmail("[email protected]");

            return $user;
        }
    }

For more info take a look over here

Also your routing should be defined like this.

routing.yml

users:
    type:     rest
    resource: Acme\ApiBundle\Controller\UsersController

FOSRest can automatically generate the routes for you if you stick to the rules as explained in the documentation.

Please take your time and read the documentation since it looks obvious that you didn't if I look at your code.

Don answered 26/2, 2014 at 23:19 Comment(4)
Hi, I tried changing the parent controller class to FOSRestController, however, the error, persists, then I realized that your answer has a different action than the one I wrote, "postUserAction" instead of "postAction". If I change this, I get "The controller for URI \"\/user\" is not callable" errorMarvel
I changed my answer... And again please make sure you read the documentationDon
Actually I did read the docs, but none of those worked for me, the auto generated routes are not found anyway... I'm done with this, is just a waste of time, I ended up using plain symphony. Besides, If I stick to the docs, there is no mention of FOSRestController, but of FosRestController and son on... Thanks for your tone ;) Not voting down however ;)Marvel
FYI: The link to the routing documentation is broken. Update to http://symfony.com/doc/current/bundles/FOSRestBundle/5-automatic-route-generation_single-restful-controller.htmlTootsie
P
1

I know you said in a comment you were giving up but you should try this if you still want to build a REST api. I think your config.yml is wrong. You have to specify what is the priority of the page formats to be sure that the first selected is json (even if you wrote it in the route, it's not enough).

Try to change your config file to be like this :

#...
fos_rest:
    view:
        view_response_listener: force
    format_listener:
        default_priorities: ['json', 'html', '*/*']
        fallback_format: json
        prefer_extension: true
#...

Here is a really good article on how to build correct REST Api :

http://williamdurand.fr/2012/08/02/rest-apis-with-symfony2-the-right-way/

Planetesimal answered 17/3, 2014 at 22:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.