Mixing route and query parameters using FOSRestBundle with Symfony

futureal picture futureal · Dec 8, 2012 · Viewed 16k times · Source

Using Symfony2 and FOSRestBundle I am attempting to implement API methods that have some number of fixed parameters defined in the route along with some optional parameters that may exist in the query string.

For example:

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

According to the documentation for FOSRestBundle, ParamFetcher is the proper way to do this, using the @QueryParam annotation. However, I already have a controller defined like:

 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');
   }

 }

Now it seems I need to be able to get access to an instance of ParamFetcher, but I don't know how (and Google searches have not helped much). I know from the documentation that I can simply change the method signature to incorporate ParamFetcher, however, when I do that it moves the parameters into the query string, which I can't have.

Is there a way to mix the two, or should I give up on ParamFetcher and go to just inspecting the request directly using Symfomy's built-in Request object?

Answer

Konrad Podgórski picture Konrad Podgórski · Sep 18, 2013

This question is quite old and you probably found a solution already but since I got here through Google search and know an answer I will contribute.

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);
    }
}