Gambling Sites Not On GamstopUk Gambling Sites Not On GamstopCasinosNon Gamstop CasinoUK Online CasinosGambling Sites Not On GamstopTrusted Non Gamstop Casinos 2025Non Gamstop Casinos UK
DRAFT / WORK IN PROGRESS

Symfony Controller not extending FOSRest Bundle

Symfony Controller Best Practice by not extending a Base Controller but injecting dependencies

Most examples of a Symfony Controller extend FOSRestController. This is not ideal, it is better to have Controllers as a Service, just like any other Service. This is much easier to Unit Test with tools like PHPUnit and PHPSpec and then forces the Controllers to do less and have less dependencies - we all like Thin Controllers.

Below is a standard example of a Controller.

<?php
namespace Your\Namespace\Controller
use FOS\RestBundle\Controller\FOSRestController;
class UsersController extends FOSRestController
{
    public function getUsersAction()
    {
        $data = ...; // get data, in this case list of users.
        return $this->handleView(
            $this->view($data, 200)
        );
    }
}

To run it as a Service is quite easy and Decouples it from Symfony FOSRest Bundle, which will look like below.

<?php
namespace Your\Namespace\Controller
class UsersController
{
    /** @var Controller */
    private $controller;
    /**
     * @param Controller $controller
     */
    public function __construct(ControllerInterface $controller)
    {
        $this->controller = $controller;
    }
    public function getUsersAction()
    {
        $data = ...; // get data, in this case list of users.
        return $this->controller->handleView(
            $this->controller->view($data, 200)
        );
    }
}

I introduced a new class here called Controller, this will proxy through to the Symfony FOSRestController - it too will have Unit Tests.

<?php
namespace Your\Namespace\Controller
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandler;
/**
 * Class Controller
 */
class Controller implements ControllerInterface
{
    /** @var ViewHandler */
    private $viewHandler;
    /** @var View */
    private $view;
    /**
     * @param ViewHandler $viewHandler
     * @param View $view
     */
    public function __construct(ViewHandler $viewHandler, View $view)
    {
        $this->viewHandler = $viewHandler;
        $this->view        = $view;
    }
    /**
     * @param View $view
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handle(View $view)
    {
        return $this->viewHandler
            ->handle($view);
    }
    /**
     * @param  array $data
     * @return View
     */
    public function setData(array $data)
    {
        return $this->view
            ->setData($data);
    }
}

The services.yml will look something like this:

services:
    your_app.fos_rest.view.view:
        class: FOS\RestBundle\View\View
        factory: [FOS\RestBundle\View\View, create]
    your_app.controller:
        class: Your\Namespace\Controller\Controller
        arguments: [@fos_rest.view_handler, @your_app.fos_rest.view.view]
    your_app.controller.users:
        class: Your\Namespace\Controller\UsersController
        arguments: [@your_app.controller]

The routing.yml will be like so:

your_app_users:
    type:     rest
    resource: your_app.controller.users

I hope that helps. Feedback welcome.

Update: Controller Interface added.

Share this on →