使用FOSRestBundle和Symfony混合路由和查询参数

时间:2012-12-08 20:31:15

标签: symfony symfony-2.1 fosrestbundle

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

例如:

 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对象检查请求?

2 个答案:

答案 0 :(得分:13)

这个问题已经过时了,您可能已经找到了解决方案,但是自从我通过Google搜索到达并知道答案后我会做出贡献。

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 :(得分:5)

只是想发布一个答案,因为原始答案仅使用QueryParams,问题是将QueryParams与RouteParams一起使用。

如果你想使用route params和query params,你可以使用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

}