Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@RouteResource does not work

I'm using FosRestBundle and I'm declaring a controller with manually routes.

namespace Cboujon\PropertyBundle\Controller;

use FOS\RestBundle\Controller\Annotations\QueryParam;
use FOS\RestBundle\Controller\Annotations\RouteResource;
use FOS\RestBundle\View\View;
use FOS\RestBundle\Controller\Annotations\Get;


/**
 * Property controller.
 * @RouteResource("Property")
 */
class PropertyRESTController extends \FOS\RestBundle\Controller\FOSRestController {


    /**
     * 
     * @return type
     * @Get("/types")
     * 
     */
    public function getTypesAction() {
        ...
        return $this->get('fos_rest.view_handler')->handle($view);
    }

}

routing.yml

cboujon_property_property_api:
    resource: "@CboujonPropertyBundle/Controller/PropertyRESTController.php"
    type:     rest
    prefix:   /api

When I do the request http://localhost:8000/api/properties/types or http://localhost:8000/api/property/types I get

404 Not Found - NotFoundHttpException.

But if http://localhost:8000/api/types it works!

I need to config the url http://localhost:8000/api/properties/types. What am I doing wrong?

Update 1

There is no Property entity. PropertyController should do custom operations (No CRUD).

Update 2

You can see the git repository

like image 949
Cristhian Boujon Avatar asked Oct 05 '15 00:10

Cristhian Boujon


1 Answers

You simply cannot mix implicit and explicit route generation (for a single route) in FOSRestBundle.

@RouteResource is meant for "prefixing" during implicit route generation, while @Get is meant for explicit routing.

Also, implicit routing is meant to speedup standard CRUD resource editing, so it is NOT your case: just go for the explicit routing and avoid all the complication. You can still benefit of other FOSRestBundle features, like View handler, @ParamFetchers, ...

Why

With implicit route generation, the route is extracted from the method name (e.g. postTypeAction becomes something like POST /type, cgetTypeAction becomes something like GET /types).

If you choose the explicit way, you use @Route, @Get, @Post, ... annotations, to set the resource URL to whatever you want. With explicit routing, @RouteResource doesn't make sense; just use the standard Symfony prefixes.

The annotation @RouteResource on the other hand, is there so that you can customize the route resource name (e.g. get_RESOURCE_myaction).

Debug you code

To clarify, here some output of app/console debug:router from your code (I've applied some syntax fix to your project to run this commands).

NOTE: I've set the prefix to /api/prefix to avoid confusions

@RouteResource + @Get (This explain why you get 404 errors):

 Name                     Method Scheme Host Path                              
 get_property_types       GET    ANY    ANY  /api/prefix/types.{_format}   

@RouteResource only (note that implicit naming take place):

 Name                     Method Scheme Host Path                              
 get_property_types       GET    ANY    ANY  /api/prefix/property/types.{_format}

@Get only (note it is the same of your current scenario, just the route name changes since is not set in @Get):

 Name                     Method Scheme Host Path                              
 get_types                GET    ANY    ANY  /api/prefix/types.{_format}

Removing both (is still the same, but.. just a coincidence since your method is called getTypesAction):

 Name                     Method Scheme Host Path                              
 get_types                GET    ANY    ANY  /api/prefix/types.{_format}       

An Off-Topic Note

In OOP, a static abstract function cannot be defined. A static method is defined at class level, so no polymorphism can take place because PHP cannot know in advance which sub-class is to be used. When the method is NOT static, PHP knows the object class (since can access $this) and you can have polymorphic behaviour.

In your class Cboujon\PropertyBundle\Entity\Property you need to remove the method static abstract function getLabel or define it as abstract function getLabel.

like image 118
giosh94mhz Avatar answered Oct 11 '22 17:10

giosh94mhz