-->

How to add a general URI prefix to all routes of a

2019-07-24 08:33发布

问题:

I have started to implement controllers for an application that is being developed with Symfony. This is my first attempt at using both Symfony and PHP at that task: I usually work with Java, together with either JAX-RS or Spring. I followed this tutorial.

My test class is as follows and the URI /tags works as expected:

namespace AppBundle\Controller;

use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class TagController extends FOSRestController
{
    /**
     * @Rest\Get("/tags")
     */
    public function getTagsAction(Request $request)
    {
        $data = ['getTagsAction' => 'not implemented yet'];
        $view = $this->view($data, Response::HTTP_OK);
        return $view;
    }
}

I would like to have, using annotations only, all routes automatically prefixed with "api", so that instead of /tags, the clients would use /api/tags.

Is it possible to define such a general prefix that would automatically be prepended to the routes of all functions? Reading the documentation, I thought this Docblock addition would be the answer:

/**
 * @Rest\Prefix("/api")
 */
class TagController extends FOSRestController
{
...
}

However, this answer to another question seems to give a different meaning to the @Prefix annotation.

Also, is there a route cache somewhere? A change to the route (to tag instead of tags) isn't picked up. I suspect there's an action to take to inform the framework of a change of a route or of the addition of a new controller.

[EDIT] There is indeed a cache in /var/cache. I believe the reason why the console picks up changes that are seemingly ignored via the browser is that the console assumes dev environment whereas access via the browser goes through app.php (and not app_dev.php). This is confirmed by the fact that php bin/console debug:router --env=prod returns a different set of routes than php bin/console debug:router (environment specification removed). Changes to routes or methods are effective in the browser after clearing the cache: php bin/console cache:clear --env=prod.

回答1:

You can use the route annotation in your class like:

/**
 * @Route("/api")
 */
class TagController extends FOSRestController
{
    ...


回答2:

Works for me:

use FOS\RestBundle\Controller\Annotations as Rest;

/**
 * Class UsersController
 * @package AppBundle\Controller
 * @Rest\Route("api/user")
 */
class UsersController extends FOSRestController implements ClassResourceInterface
{

    /**
     * Creates a new User
     *
     * @Rest\Post("/create")
     * @param Request $request
     * @return View
     */
    public function createAction(Request $request)
    {

Then when I access /api/user/create - everything works.



回答3:

Using @Route didn't work in my case. Looks like that approach is obsolete with more recent releases of Symfony/FOSRestBundle. However, there is @Prefix perfectly working in my case:

use FOS\RestBundle\Controller\Annotations as Rest;

/**
 * @Rest\Prefix("api")
 */
class CustomersController {
    public function getCustomersAction() {}
    public function newCustomersAction() {}
    public function getCustomerAction( $slug ) {}
    public function editCustomerAction( $slug ) {}
    public function removeCustomerAction( $slug ) {}
}

This eventually results in console debug:router listing this:

bash-4.4# bin/console debug:router
 -------------------------- -------- -------- ------ ---------------------------------------- 
  Name                       Method   Scheme   Host   Path                                    
 -------------------------- -------- -------- ------ ---------------------------------------- 
  new_customers              GET      ANY      ANY    /api/customers/new.{_format}            
  edit_customer              GET      ANY      ANY    /api/customers/{slug}/edit.{_format}    
  remove_customer            GET      ANY      ANY    /api/customers/{slug}/remove.{_format}  
  get_customers              GET      ANY      ANY    /api/customers.{_format}                
  get_customer               GET      ANY      ANY    /api/customers/{slug}.{_format}         
 -------------------------- -------- -------- ------ ----------------------------------------