Не удалось найти шаблон при возврате ответа с помощью FOSRestBundle

Я использую FOS Rest Bundle для создания API, проблема в том, что каждый раз, когда я пытаюсь вернуть что-либо, я получаю сообщение об ошибке: «Невозможно найти шаблон». Я действительно не хочу отображать шаблон, а сериализовать сущность, которая у меня есть.

Вот мой код:

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;
        }
    }

и мой 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

Буду очень признателен за любую помощь!

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"
        }
    }
}

person danielrvt    schedule 26.02.2014    source источник
comment
возможный дубликат остаточного пакета FOS: не удалось найти шаблон   -  person Francesco Casula    schedule 25.09.2015


Ответы (3)


Это происходит потому, что вы, вероятно, используете браузер для тестирования своего API. Если вы откроете свой инспектор консоли, вы увидите, какой запрос ваш браузер отправляет вашему API. Как видите, заголовок Accept выглядит примерно так:

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

Как видите, первый принятый формат — text/html. Вот почему я предполагаю, что ваше приложение пытается вернуть HTML-ответ, но не может найти шаблон!

Поэтому я предлагаю вам отключить формат html, если он вам не нужен, и установить json в качестве формата по умолчанию.

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

С такой конфигурацией вы говорите, что поддерживаете только форматы json и xml, и, если ни один из них не указан, используйте json. Теперь снова откройте браузер, и вы получите свой ресурс в виде XML. Это связано с тем, что заголовок Accept по-прежнему имеет значение Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8. Ваш браузер не знает, что вы вызываете Rest API и какой формат предпочитаете :-)

Чтобы протестировать ваш API, я предлагаю вам использовать правильный клиент. Если вы используете Chrome, взгляните на расширение Advanced REST client.

person Francesco Casula    schedule 25.09.2015

Я думаю, вы используете не тот контроллер, попробуйте вместо этого использовать FOSRestController. Код вашего контроллера должен быть примерно таким.

<?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;
        }
    }

Для получения дополнительной информации см. здесь

Также ваша маршрутизация должна быть определена следующим образом.

routing.yml

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

FOSRest может автоматически генерировать маршруты для вас, если вы придерживаетесь правил, как описано в документация.

Пожалуйста, не торопитесь и прочитайте документацию, так как очевидно, что вы не если я посмотрю на ваш код.

person Geert Wille    schedule 26.02.2014
comment
Привет, я попытался изменить класс родительского контроллера на FOSRestController, однако ошибка сохраняется, затем я понял, что ваш ответ имеет другое действие, чем то, которое я написал, postUserAction вместо postAction. Если я изменю это, я получаю Контроллер для URI \\/user\ is not callable error - person danielrvt; 27.02.2014
comment
Я изменил свой ответ... И еще раз, убедитесь, что вы прочитали документация - person Geert Wille; 27.02.2014
comment
На самом деле я читал документы, но ни один из них не работал у меня, автоматически сгенерированные маршруты все равно не найдены ... Я закончил с этим, это просто пустая трата времени, в итоге я использовал простую симфонию. Кроме того, если я придерживаюсь документации, там не упоминается FOSRestController, но упоминается FosRestController и его сын... Спасибо за ваш тон;) Однако не голосую;) - person danielrvt; 27.02.2014
comment
К вашему сведению: ссылка на документацию по маршрутизации не работает. Обновите до http://symfony.com/doc/current/bundles/FOSRestBundle/5-automatic-route-generation_single-restful-controller.html - person Chris Brown; 30.12.2015

Я знаю, что вы сказали в комментарии, что отказываетесь, но вам следует попробовать это, если вы все еще хотите создать REST API. Я думаю, что ваш config.yml неверен. Вы должны указать, каков приоритет форматов страниц, чтобы быть уверенным, что первым выбранным является json (даже если вы написали это в маршруте, этого недостаточно).

Попробуйте изменить файл конфигурации, чтобы он выглядел так:

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

Вот действительно хорошая статья о том, как построить правильный REST Api:

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

person Ianlet    schedule 17.03.2014