Fosrestbundle: Versioning: How to map Route Prefix to Version Listener

Created on 6 Apr 2017  路  8Comments  路  Source: FriendsOfSymfony/FOSRestBundle

Hi,

new to Symfony and FOSRestBundle, I am curious if there is an easy way to "map" a route prefix for a versioned URI to the Version Listener?

Considering the following example setup:

config.xml

fos_rest:
    param_fetcher_listener: force # map all configured query parameters to request attributes
    versioning:
        enabled: true
        default_version: latest

routing.yml

api_with_prefix:
    type:         rest
    prefix:       /{version}
#    requirements:
#        version:  latest|v1|v2
    name_prefix:  api_
    resource:     ApiBundle\Controller\ProductsController

ProductsController.php

<?php

namespace ApiBundle\Controller;

use FOS\RestBundle\Controller\Annotations\RouteResource;
use FOS\RestBundle\Controller\Annotations\Version;
use FOS\RestBundle\Controller\FOSRestController;

/**
 * Class ProductsController
 * @RouteResource("Product")
 * @Version({"v1", "v2", "latest"})
 */
class ProductsController extends FOSRestController
{
    /**
     * c stands for Collection
     * /products
     * @return string
     */
    public function cgetAction()
    {
        $apiversion = $this->get('fos_rest.versioning.listener')->getVersion();
        return $apiversion;
   }
}

The route works when specifying an Accept Header or Request Parameter manually, the output equals the given version.

Of course the Versioning Listener does not take into account what the URI prefix is.

But from the docs there seems to be a way when dealing with Path instead of Prefix:
http://symfony.com/doc/master/bundles/FOSRestBundle/versioning.html#uri-api-versioning

Note: this will override the version attribute of the request if you use the FOSRestBundle versioning.

I already searched on SO, the open & closed Issue on FOSRestBundle and Symfony 3, even some commits where parts of the docs were removed.

Can anybody point me into the right direction to support URI API Versioning, too?

Edit: Probably related to #1529?

Cheers,
Frederik

All 8 comments

@winkelsdorf You are right. This is the same issue as #1529. That's why I closed here as a duplicate. Can you please check in the meantime if the changes proposed in #1639 will fix the issue for you?

@xabbuh Yes, I can confirm that PR #1639 fixes my issue completely.

As a side note: $this->get('fos_rest.versioning.listener')->getVersion() throws an exception when using the PR, but this might be related to other changes in master as I used a tagged version before (^2.1).

Exception:

[2017-04-10 09:33:00] php.CRITICAL: Fatal Error: Call to undefined method 
    FOS\RestBundle\EventListener\VersionListener::getVersion() {"exception":"[object] 
    (Symfony\\Component\\Debug\\Exception\\FatalErrorException(code: 0): 
    Error: Call to undefined method 
    FOS\\RestBundle\\EventListener\\VersionListener::getVersion() at 
    /Users/winkelsdorf/Projects/GitHub/Rest-API/src/ApiBundle/Controller/ProductsController.php:26)"} []
[2017-04-10 09:33:00] request.CRITICAL: Uncaught PHP Exception
   Symfony\Component\Debug\Exception\UndefinedMethodException: 
  "Attempted to call an undefined method named "getVersion" of class
     "FOS\RestBundle\EventListener\VersionListener"." at 
    /Users/winkelsdorf/Projects/GitHub/Rest-API/src/ApiBundle/Controller/ProductsController.php 
    line 26 {"exception":"[object]  
   (Symfony\\Component\\Debug\\Exception\\UndefinedMethodException(code: 0): 
    Attempted to call an undefined method named \"getVersion\" of class
     \"FOS\\RestBundle\\EventListener\\VersionListener\". at 
    /Users/winkelsdorf/Projects/GitHub/Rest-API/src/ApiBundle/Controller/ProductsController.php:26)"} []

As far as I can see, version attribute is still populated, but it looks like there is no more public getVersion method?

@winkelsdorf Actually, the getVersion() method was never meant to be used outside the listener.

@xabbuh That's what I thought, I likely found it through an outdated documentation earlier. Using the parameter with key version from the Request bag works fine though. Thanks for the clarification!

@winkelsdorf FYI, this was done in #1605 (see especially https://github.com/FriendsOfSymfony/FOSRestBundle/pull/1605#discussion_r87572762).

@xabbuh fyi: Proposed PR still does not fix all issues with URI versioning (wrong controller matched). Sadly I am unable to use router:match as soon as version annotation is used. It gives a RuntimeException with Unable to get a property on a non-object. for the route.

Regarding the URI versioning - should I open a new issue or post a (lengthy) comment in the PR?

@winkelsdorf I'd say let's start with a comment there and see if it fits in its context. We can move it to its own issue anyway if we think that's better then.

@xabbuh Agreed and done. If the discussion gets too complex for the PR it can later be moved to it's own issue for dealing with #1691, #1529 and #1491 altogether.

Was this page helpful?
0 / 5 - 0 ratings