Search code examples
restsymfonyfosrestbundlesymfony-2.8

How to singularize route path part using FOSRestBundle


I have this controller (a snippet here)

/**
 * Class UserController
 * @package Belka\AuthBundle\Controller
 */
class UserController extends FOSRestController implements ClassResourceInterface
{
    /**
     * @View()
     *
     * @Route(requirements={"user"="\w+"})
     * @ParamConverter("user", converter="fos_rest.request_body")
     */
    public function postGlobaltokenAction(User $user)
    {
        ...
    }

that automatically generates the route:

  post_user_globaltoken      POST     ANY      ANY    /api/users/{user}/globaltokens.{_format}  

which is OK, except for the fact I would like "globaltoken" singularized. Is that possible? I cannot find any annotation to tweak this. Should I hardcode the route in my route.yml?


Solution

  • I've found two ways:

    Using a personal Inflector

    as Symfony's documentation suggests, you can register a personal Inflector which returns "globaltoken" always as singular, whereas all the other resources will be pluralized:

    use Doctrine\Common\Util\Inflector;
    use FOS\RestBundle\Util\Inflector\DoctrineInflector;
    use FOS\RestBundle\Util\Inflector\InflectorInterface;
    
    /**
     * Inflector class
     *
     */
    class NoopInflector extends DoctrineInflector implements InflectorInterface
    {
        public function pluralize($word)
        {
            if($word == "globaltoken")
                return $word;
    
            return parent::pluralize($word);
        }
    }
    

    services.yml:

    services:
        belka.auth_bundle.util.inflector:
          class: Belka\AuthBundle\Util\NoopInflector
    

    but I found this way a bit dirty, as I could need the plural form in the future.

    Overriding the FOSRestBundle auto-generated routes

    It's that simple! Just add the @Route annotation on the right methos and you're done!

    /**
     * @View()
     *
     * @Route("/users/{user}/globaltoken", defaults={"_format" = "json"}, requirements={"user"="\w+"})
     *
     * @ParamConverter("user", converter="fos_rest.request_body")
     */
    public function postAction(User $user)
    {
    }
    

    Now if I call php app/console debug:route I get what I want:

    post_user_globaltoken      POST     ANY      ANY    /api/users/{user}/globaltoken.{_format}