Как использовать ручные маршруты FOSRestBundle с CRUD из Symfony2?

Я использую FOSRestBundle для создания приложения REST, но поскольку функции REST являются лишь частью, я также использую некоторые встроенные инструменты автоматизации Symfony2 для генерации моего кода CRUD. Все работает нормально, но я не могу правильно сопоставить маршрут, и я буду признателен за некоторые идеи и примеры того, как это сделать вручную. Я прочитал определение маршрута вручную в руководстве FOS, в котором говорится об использовании данных аннотаций, но как мне это сделать, поскольку код CRUD, созданный Symfony2, использует другую аннотацию?

Вот пример:

class UserController extends Controller
{

    /**
     * Lists all User entities.
     *
     * @Route("/", name="user")
     * @Method("GET")
     * @Template()
     */
     public function indexAction()
     {
         $em = $this->getDoctrine()->getManager();

         $entities = $em->getRepository('CompanyWebServicesBundle:User')->findAll();

         return array(
             'entities' => $entities,
         );
     }

В руководстве FOSRest аннотация для GET представлена ​​как use FOS\RestBundle\Controller\Annotations\Get;.

/**
 * GET Route annotation.
 * @Get("/likes/{type}/{typeId}")
 */

Когда я использую маршрут как /index, это дает мне ошибку, и мое определение маршрута в config.yml:

index:
     type: rest
     resource: Company\WebservicesBundle\Controller\UserController

Как я могу исправить эту проблему?


person Paul A.    schedule 22.11.2013    source источник


Ответы (1)


На вашем месте я бы создал отдельные пакеты для ваших контроллеров REST и общих контроллеров CRUD. Это упростит обслуживание (на мой взгляд). Например, создайте AcmeMainBundle и AcmeRestBundle, а затем создайте отдельный класс для фактического выполнения действий, которые вы будете вызывать из обоих пакетов. Что-то вроде этого:

// src/Acme/MainBundle/Crud/User.php (create this folder structure)

class User{
    private $em;

    public function __construct($em){
        $this->em = $em;
    }

    public function getUser($id){
        return $this->em->getRepository('AcmeMainBundle:User')->find($id);
    }
}

Потом:

// src/Acme/MainBundle/Controller/UserController.php

use Symfony\Component\HttpFoundation\Request;
use Acme\MainBundle\Crud\User;

class UserController extends Controller {
    public function getAction($request){
        $em = $this->getDoctrine()->getManager();
        $getUser = new User($em);
        $user = $getUser ->getUser($request->query->get('user_id'));

        // return response
    }
}

А потом:

// src/Acme/RestBundle/Controller/UserController.php

use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Routing\ClassResourceInterface;
use Symfony\Component\HttpFoundation\Request;

class UserController extends Controller implements ClassResourceInterface {
    /**
     * @Rest\View()
     */
    public function getAction($id){
        $em = $this->getDoctrine()->getManager();
        $getUser = new User($em);
        $user = $getUser ->getUser($id);

        // return using the default format defined in config.yml
        return array(
            "success"=>'true',
            "user" => $user
        );
    } // get_user  [GET] /users/{id}
}

Обратите внимание, что использование ClassResourceInterface означает, что имена ваших методов будут использоваться для генерации маршрутов. см. FOSRestBundle Docs, чтобы узнать об этом подробнее.

Вы можете сделать что-то подобное для всего вашего CRUD, таким образом, вы сохраните свои маршруты отдельными и обслуживаемыми, но при этом у вас останется единая база кода для обновления.

person Sehael    schedule 22.11.2013
comment
Не могли бы вы указать, как я могу указать путь для доступа к контроллерам CRUD и REST, скажем, из браузера? Я просто хочу, чтобы один базовый пример работал, а затем я мог бы извлечь из него уроки. Спасибо! - person Paul A.; 25.11.2013
comment
если вы следуете методу, который я использовал с FOSRestBundle, путь для тестирования будет /users/{id}. Обычные контроллеры CRUD следуют тем же соглашениям, что и любое приложение symfony2. Создайте представление, создайте контроллер для визуализации представления и создайте маршрут, который будет вызывать контроллер. - person Sehael; 25.11.2013
comment
Действительно ли мне нужны два набора маршрутов, если те, которые сгенерированы symfony2, уже работают, зачем мне оба? Что FOSRestBundle будет делать иначе? Я спрашиваю об этом, потому что теперь у меня два экземпляра, и это немного сбивает с толку, почему я не могу использовать CRUD, созданный только Symfony2? - person Paul A.; 07.12.2013
comment
Я думаю, это зависит от того, как вы хотите создать свое приложение. Если вы создаете свое приложение на основе ответов API (JSON, xml, ...), то все, что вам нужно, - это REST API. Если вы хотите использовать инструменты Symfony (например, формы), тогда ответы API не будут работать, вам нужно будет вернуть представление. - person Sehael; 08.12.2013