11

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

Cristhian Boujon
  • 4,060
  • 13
  • 51
  • 90
  • The `RouteResource` looks like it's just to change the name (eg, `FooController` using the resource `Property` rather than `Foo`). It looks like your routing.yml should have `parent: property` in the definition for the `types` routes. – qooplmao Oct 05 '15 at 12:03
  • @Qoop, sorry but I don't understand, why my routing.yml should have `parent: property`? My other controllers defined does not need it and I didn't have any error with them. – Cristhian Boujon Oct 05 '15 at 13:21
  • you dont need `RouteResource` annotation when you will define custom routes for all Controller actions and if you will define prefix for all actions, can use `@Prefix` anotation on class controller – ghanbari Oct 13 '15 at 09:56

3 Answers3

10

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.

giosh94mhz
  • 2,908
  • 14
  • 25
0

If I understood you correctly you should change prefix in routing.yml from

perifx: /api

to

prefix: /api/properties

to have this url http://localhost:8000/api/properties/types

0

Well, you can simply remove the @GET annotation from your getTypesAction() method and rely on the default route creation behaviour of FOSRestBundle (your method will then be accessible via /api/property/types).

Edit: Basically, this is what is described on http://symfony.com/doc/master/bundles/FOSRestBundle/5-automatic-route-generation_single-restful-controller.html#define-resource-actions.

xabbuh
  • 5,801
  • 16
  • 18