Bertuz
Bertuz

Reputation: 2566

FOSRestBundle is not considering the format in my URL

I want to consider the format extension in my URLs so that it takes the highest priority for the _format parameter. My configuration is the following one:

fos_rest:
    param_fetcher_listener: true
    view:
        view_response_listener: 'force'
        formats:
          json: true
          xml: true
    routing_loader:
        default_format: json
    format_listener:
        enabled: true
        rules:
          - { path: '^/api', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true }
    serializer:
        serialize_null: true
    body_converter:
        enabled: true

and my HTTP request is the following one:

POST /app_dev_local.php/api/users/admin/globaltoken.json HTTP/1.1
Host: localhost:8000
Cache-Control: no-cache

{
    "password": "<a password>"
}

this generates an exception like this:

{"error":{"code":415,"message":"Unsupported Media Type","exception":[{"message":"The format \"txt\" is not supported for deserialization.","class":"Symfony\\Component\\HttpKernel\\Exception\\UnsupportedMediaTypeHttpException","trace":[{"namespace":"","short_class":"","class":"","type":"","function":"","file":"\/Users\/Matteo\/Documents\/belka\/auth\/vendor\/friendsofsymfony\/rest-bundle\/FOS\/RestBundle\/Request\/AbstractRequestBodyParamConverter.php","line":121,"args":[]},{"namespace":"FOS\\RestBundle\\Request","short_class":"AbstractRequestBodyParamConverter","class":"FOS\\RestBundle\\Request\\AbstractRequestBodyParamConverter","type":"->","function":"execute","file":"\/Users\/Matteo\/Documents\/belka\/auth\/vendor\/friendsofsymfony\/rest-bundle\/FOS\/RestBundle\/Request\/RequestBodyParamConverter.php

where the interesting part is:

"Unsupported Media Type","exception":[{"message":"The format \"txt\"

so I tried to change my HTTP request like this:

POST /app_dev_local.php/api/users/admin/globaltoken.json HTTP/1.1
Host: localhost:8000
Content-Type: application/json
Cache-Control: no-cache

{
    "password": "<a password>"
}

and it works! My extension is totally ignored I guess. Is there something wrong with my configuration? Is it because of a JMSSerializer misconfiguration? Here is my annotations:

/**
 * @View()
 *
 * @Route("/users/{username}/globaltoken", requirements={"user"="\w+"})
 * @ParamConverter(
 *     "userBody",
 *     class="Belka\AuthBundle\Entity\User",
 *     converter="fos_rest.request_body",
 *     options={"deserializationContext"={"groups"={"personal"}}}
 * )
 */
public function postAction($username, User $userBody)

Upvotes: 0

Views: 3362

Answers (2)

xandrucancelas
xandrucancelas

Reputation: 49

for me the problem was that I was sending the form data serialized and I solved with an array:

var dataj = {
                    name: (tjq('input[name="appbundle_contact[name]"]').val()),
                    description: (tjq('input[name="appbundle_contact[description]"]').val()),
                    email: (tjq('input[name="appbundle_contact[email]"]').val()),
                    country: (tjq('input[name="appbundle_contact[country]"]').val()),
                    phone: (tjq('input[name="appbundle_contact[phone]"]').val()),
                };
                tjq.ajax({
                    type        : tjq('#contactForm').attr( 'method' ),
                    url         : tjq('#contactForm').attr( 'action' ),
                    jsonp: "response",
                    dataType: 'json',
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify(dataj),
                    success     : function(data, status, object) {
                        tjq('.alert-success').show();
                        tjq('#contactForm').hide();
                    },
                    error: function(data, status, object){
                        console.log(data.message);
                        tjq('.alert-error').show();
                        tjq('#contactForm').hide();
                    }
                });

Hope this works for you ;)

Upvotes: 0

Nicholas Shanks
Nicholas Shanks

Reputation: 10971

With a request, the Content-Type header defines the media type of the request body. The URL you POST to has no effect, and the default media type for request bodies is text/plain, so this behaviour is correct.

You could, for example, do this:

PUT /foo.json
Content-Type: application/x-www-form-urlencoded

this=that

 

200 OK

  Then:

GET /foo.json

 

200 OK
Content-Type: text/json; charset=utf-8

{"this":"that"}

Upvotes: 2

Related Questions