2012-12-08 37 views
8

使用Symfony2和FOSRestBundle我试图实现API方法,这些API方法在路由中定义了一些固定参数以及查询字符串中可能存在的一些可选参数。使用Symfony中的FOSRestBundle混合路由和查询参数

例如:

http://somesite.com/api/method/a/b 
http://somesite.com/api/method/c/d?x=1&y=2 

the documentation for FOSRestBundle,ParamFetcher是要做到这一点,利用@QueryParam标注的正确方法。不过,我已经有一个控制器,定义如下:

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use FOS\RestBundle\Controller\Annotations\Get; 
use FOS\RestBundle\Controller\Annotations\View; 

class MyController extends Controller 
{ 

    /** 
    * @Get("/method/{a}/{b}") 
    * @View() 
    */ 
    public function getMethodAction($a, $b) 
    { 
    // do stuff 

    return array('foo' => 'bar'); 
    } 

} 

现在看来,我需要能够获得访问ParamFetcher的实例,但我不知道如何(以及谷歌搜索并没有帮助太多) 。我从文档中知道,我可以简单地改变方法签名来并入ParamFetcher,但是,当我这样做时,它将参数移动到查询字符串中,这是我不能拥有的。

是否有混合两者的方法,还是应该放弃ParamFetcher并直接使用Symfomy的内置Request对象直接检查请求?

回答

12

这个问题是相当古老的,你可能已经找到了解决方案,但自从我通过谷歌搜索来到这里,并知道我会贡献的答案。

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Symfony\Component\HttpFoundation\JsonResponse; 
use FOS\RestBundle\Request\ParamFetcher; 
use FOS\RestBundle\Controller\Annotations\QueryParam; 
use Nelmio\ApiDocBundle\Annotation\ApiDoc; 

class DefaultController extends Controller 
{ 
    /** 
    * Returns a collection of Task 
    * 
    * @QueryParam(name="projectId", nullable=true, requirements="\d+") 
    * @QueryParam(name="name", nullable=true, description="Project Name") 
    * @QueryParam(name="assignee", nullable=true) 
    * @QueryParam(name="depth", nullable=true) 
    *   * 
    * @param ParamFetcher $paramFetcher 
    * @ApiDoc() 
    * 
    * @return JsonResponse 
    */ 
    public function cgetTaskAction(ParamFetcher $paramFetcher) 
    { 
     foreach ($paramFetcher->all() as $criterionName => $criterionValue) { 
      // some logic here, eg building query 
     } 

     $results = // query database using criteria from above 

     // this is just a simple example how to return data 
     return new JsonResponse($results); 
    } 
} 
+1

感谢您的跟进 - 我终于弄清楚了这一点,并忽略了回来。 – futureal

5

只是想发布一个答案,因为原来的答案只使用QueryParams,并使用QueryParams问题连同RouteParams。

如果您想要使用路径参数和查询参数,可以使用ParamFetcher作为动作的第一个参数,并稍后添加路由参数。

我还没有找到一种方法将路径参数添加到paramFetcher。

/* 
* @Route("/term/{termId}", requirements={"termId" = "[a-z0-9]+"}) 
* 
* @QueryParam(name="limit", requirements="\d+", default="30", description="How many documents to return.") 
* 
* @Method("GET") 
* 
* @param ParamFetcherInterface $paramFetcher 
* @param $termId 
* @return array() 
*/ 
public function getTermFeedAction(ParamFetcherInterface $paramFetcher, $termId) { 
    // access $termId over the method parameter 
    // access the @queryparams via the $paramFetcher 

} 
+0

更好的答案,因为它不会中断路由参数注入。 – Ryall