0

I am using the FOSRestBundle to create a REST application but since REST features is only a part, I am also using some of Symfony2 built-in automation tools to generate my CRUD code. Everything works fine but I am unable to correctly map the route and I will appreciate some insight and example on how to do this manually. I have read the manual route definition in the FOS manual stating to use the given annotations but how do I do this since the CRUD code created by Symfony2 uses a different annotation?

Here is an example:

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 manual gives the annotation for GET as use FOS\RestBundle\Controller\Annotations\Get;

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

When I use the route as /index, it gives me an error and my route definition in config.yml is:

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

How can I fix this problem?

Lughino
  • 4,060
  • 11
  • 31
  • 61
Paul A.
  • 577
  • 2
  • 11
  • 24

1 Answers1

1

If I were you, I would create separate bundles for your REST controllers and your generic CRUD controllers. This will make things easier to maintain (in my opinion). For example, create a AcmeMainBundle and a AcmeRestBundle, and then create a separate class to actually perform the actions that you will call from both bundles. Something like this:

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

Then:

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

And then:

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

Please note that using the ClassResourceInterface means your method names will be used to generate the routes. see FOSRestBundle Docs for more info on that.

You can do something similar to this for all your CRUD, that way you keep your routes separate and maintainable, but still have a single code base to update.

Sehael
  • 3,678
  • 21
  • 35
  • Could you specify how I might specify the path to access the CRUD and REST controllers lets say from the browser? I just want to get one basic example working and then I can learn from it. Thanks! – Paul A. Nov 25 '13 at 14:53
  • if you are following the method I used with the FOSRestBundle, the path to use to test would be `/users/{id}`. The normal CRUD controllers follow the same conventions as any symfony2 app. Create a view, create the controller to render the view, and create a route that will call the controller. – Sehael Nov 25 '13 at 17:26
  • Do I really need two sets of routes when the ones generated by symfony2 already works, why do I need both? What will FOSRestBundle do differently? I ask this because now I have two instances and it is a bit confusing, why can't I use the CRUD created by Symfony2 alone?? – Paul A. Dec 07 '13 at 04:08
  • I guess that depends on how you want to build your application. If you are building your application based on API responses (JSON, xml, ...), then all you need is the REST API. If you want to use Symfony tools (like forms) then API responses will not work, you will need to return a view. – Sehael Dec 08 '13 at 03:54