@RouteResource不起作用

时间:2015-10-05 00:44:56

标签: php symfony fosrestbundle

我正在使用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有效!

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

更新1

没有Property实体。 PropertyController应该执行自定义操作(无CRUD)。

更新2

您可以看到git repository

3 个答案:

答案 0 :(得分:8)

你根本无法在FOSRestBundle中混合隐式和显式路由生成(对于单个路由)。

@RouteResource用于在隐式路由生成期间“前缀”,而@Get用于显式路由。

此外,隐式路由旨在加速标准CRUD资源编辑,因此 NOT 您的情况:只需进行显式路由并避免所有复杂情况。您仍然可以从其他FOSRestBundle功能中受益,例如View处理程序,@ParamFetcher,...

为什么

通过隐式路由生成,路径从方法名称中提取(例如postTypeAction变为POST /typecgetTypeAction变成GET /types}。

如果您选择显式方式,则可以使用@Route@Get@Post,...注释将资源网址设置为您想要的任何内容。通过显式路由, @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方法是在类级别定义的,因此PHP不会发生多态性 不能事先知道要使用哪个子类。当方法不是静态的时,PHP知道对象类(因为可以访问$this)和你 可以有多态行为。

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

答案 1 :(得分:0)

如果我理解正确,你应该在

中更改routing.yml中的前缀
perifx: /api

prefix: /api/properties

拥有此网址http://localhost:8000/api/properties/types

答案 2 :(得分:0)

好吧,您只需从@GET方法中删除getTypesAction()注释,并依赖FOSRestBundle的默认路由创建行为(您的方法将可通过/api/property/types访问)。 / p>

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