@RouteResource 不起作用

@RouteResource does not work

我正在使用 FosRestBundle 并且正在声明一个带有手动路由的控制器。

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

当我执行请求 http://localhost:8000/api/properties/typeshttp://localhost:8000/api/property/types 时,我得到

404 Not Found - NotFoundHttpException.

但如果 http://localhost:8000/api/types 有效!

我需要配置 url http://localhost:8000/api/properties/types。我做错了什么?

更新 1

没有 属性 实体。 属性控制器应该执行自定义操作(无 CRUD)。

更新 2

你可以看到 git repository

如果我理解正确,你应该将 routing.yml 中的前缀从

更改为
perifx: /api

prefix: /api/properties

拥有这个urlhttp://localhost:8000/api/properties/types

嗯,您可以简单地从 getTypesAction() 方法中删除 @GET 注释并依赖 FOSRestBundle 的默认路由创建行为(然后您的方法将可以通过 /api/property/types 访问) .

编辑:基本上,这就是 http://symfony.com/doc/master/bundles/FOSRestBundle/5-automatic-route-generation_single-restful-controller.html#define-resource-actions 上描述的内容。

您不能在 FOSRestBundle 中混合隐式和显式路由生成(对于单个路由)。

@RouteResource 用于隐式路由生成期间的 "prefixing",而 @Get 用于显式路由。

此外,隐式路由旨在加速标准 CRUD 资源编辑,因此 不是 您的情况:只需进行显式路由即可避免所有复杂情况。您仍然可以受益于其他 FOSRestBundle 功能,例如视图处理程序、@ParamFetchers、...

为什么

通过隐式路由生成,路由是从方法名称中提取的(例如 postTypeAction 变成类似 POST /typecgetTypeAction 变成类似 GET /types).

如果选择显式方式,则使用 @Route@Get@Post、... 注释,将资源 URL 设置为任何你想要的.通过显式路由, @RouteResource 没有意义;只需使用标准的 Symfony 前缀。

另一方面,注解 @RouteResource 可以自定义 route resource name(例如 get_RESOURCE_myaction)。

调试你的代码

澄清一下,这里是您代码中 app/console debug:router 的一些输出(我已将一些语法修复应用到您的项目以 运行 此命令)。

注意:我已将前缀设置为 /api/prefix 以避免混淆

@RouteResource + @Get(这解释了为什么会出现 404 错误):

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

@RouteResource(注意隐式命名发生):

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

@Get(请注意,这与您当前的情况相同,只是路由名称更改,因为未在 @Get 中设置):

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

删除两者(仍然相同,但是..只是巧合,因为你的方法被称为getTypesAction):

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

一篇题外话

在 OOP 中,无法定义 static abstract functionstatic 方法定义在 class 级别,因此不会发生多态性,因为 PHP 无法事先知道要使用哪个 sub-class。当方法不是静态的时,PHP 知道对象 class(因为可以访问 $this)并且你 可以有多态行为。

在您的 class Cboujon\PropertyBundle\Entity\Property 中,您需要删除方法 static abstract function getLabel 或定义它 作为 abstract function getLabel.