Search code examples
apisymfonyversioningfosrestbundle

How to debug routes that require accept headers?


I'm following the FOSRest documentation on API versioning.

However it's not clear to me how the headers connect it to a specific controller using media_type.

Right now I'm sending the headers: Accept: application/json;version=1.0 with Chrome extension Postman to /api/user/status

However I'm getting a No route found for "POST /api/user/status" error

Here's my configuration:

routing.yml:

type: rest
prefix: /api
resource: Acme\Bundle\SomeBundle\Controller\DefaultController

DefaultController.php:

use FOS\RestBundle\Controller\Annotations\Version;

/**
 * @Version("1.0")
 * @RouteResource("User", pluralize=false)
*/
class User

...

public function postStatusAction()

config.yml

fos_rest:
    versioning:
        enabled: true
        resolvers:
            query: false
            custom_header: false
            media_type: 
                enabled: true
                regex: '/(v|version)=(?P<version>[0-9\.]+)/'
    routing_loader:
        default_format: json
    view:
        mime_types:
            json: ['application/json;version=1.0']
    format_listener:
        enabled: true

console debug:router post_user_status

| Route Name   | post_user_status                                        |
| Path         | /api/user/status.{_format}                              |
| Path Regex   | #^/api/user/status(?:\.(?P<_format>json|xml|html))?$#s  |
| Host         | ANY                                                     |
| Host Regex   |                                                         |
| Scheme       | ANY                                                     |
| Method       | POST                                                    |
| Requirements | _format: json|xml|html                                  |
| Class        | Symfony\Component\Routing\Route                         |
| Defaults     | _controller: AcmeSomeBundle:Default:postStatus         |
|              | _format: json                                           |
| Options      | compiler_class: Symfony\Component\Routing\RouteCompiler |
+--------------+---------------------------------------------------------+

I've also tried to no avail in routing.yml condition: "request.attributes.get('version') == '1.0'"

What am I missing?


Solution

  • Thanks in part to @Mohammad in the comments for pointing me in the right direction I eventually found the answer.

    While looking over the FOSRest versioning documentation again the instructions are to be taken quite literally.

    One of the requirements states

    You must configure the possible mime types for all supported versions:

    Which means that since I only had:

    view:
        mime_types:
            json: ['application/json;version=1.0']
    

    Even if the in the header sent requested an API version that didn't exist it kept defaulting to this no matter what.

    The correct config is

    view:
        mime_types:
            json: ['application/json','application/json;version=1.0']
    

    along with Mohhamad's mention that media_type headers require format_listener

    format_listener:
        enabled: true
        rules:
            - { path: '^/api', priorities: ['json'], fallback_format: json, prefer_extension: false }
    

    With this it routes correctly to the right API version number.

    It also finally routes to a 404 response if the version number is incorrect or if there is no API version header.