How do I change the default Drupal response format to JSON?

I am using Drupal services with a REST server to expose an API.
Previously, I only worked with 1 response type, JSON, so I don't need the additional ".json" extension to the URL.

Now I have to add a new formatter, XML.
Then the problem starts, all APIs without extension (.json or .xml) will be set to XML by default.

I am trying to trace this issue and finally found a related variable: "rest_server_default_response_format".
and related code on service unit getResponseFormatContentTypeNegotiations

So I have the value $ mime_candidates []

Array ( [0] => application/xml [1] => text/xml [2] => application/json )

      

Even response_format is already set as json on line 87, but mimeparse-> best_match () returns 'text / xml'.

What's the best way to override this?
I don't think it's best to use getResponseFormatContentTypeNegotiations.
is there anyway for the best_match function to prefer JSON over XML?

thank.

+3


source to share


3 answers


Through the admin user interface, you can modify the configured services only to return certain formats.

Structure> Services



then edit resources> server tab

then you can choose the response format and make it json exclusively.

+1


source


In the latest version of the Service, all actions take place in getResponseFormatContentTypeNegotiations()

a file services/servers/rest_server/includes/ServicesContentTypeNegotiator.inc

; in particular this part:

// Get the best matching format, default to json
$response_format = variable_get('rest_server_default_response_format', 'json');
$http_accept = $context->getServerVariable('HTTP_ACCEPT');
if (!empty($http_accept)) {
  $mime = $this->mimeParse();
  $mime_type = $mime->best_match($mime_candidates, $http_accept);
  $response_format = isset($mime_map[$mime_type]) ? $mime_map[$mime_type] : '';
}

      

What happens is it gets the default JSON formatting. Then, when looking at your request, accept headers. If your accept headers don't specify a valid MIME type, it will use JSON.

It seems that all modern browsers have this feature called content negotiation 'where by default they essentially indicate that they accept HTML first and then XML (although this is browser dependent).



So, given , you would expect clients to simply need to strip the XML types with their request header in order to get the JSON. Not so, unfortunately.

If the request includes any "accept" header at all, the code will try to match the header against the list of parsers you've included (let's say it's just XML, JSON) and it will either pick the one that matches or the first one. Therefore, if you have an accept header and you do not specify a valid MIME type, Services will use the first one you enabled .

To change the order of these parsers you included, I think you could use one of the hooks from services.alter.api.php

.

+1


source


The best way is to use the "Accept" header on your request:

Accept: application/json

      

If json is available it will be used as response instead of xml.

0


source







All Articles