Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Yii2 rest controller giving response in XML format?

Tags:

rest

php

yii2

Currently I am using the following initialization code on my api module

public function init()
{
    parent::init();
    Yii::$app->response->format = Response::FORMAT_JSON;
}

My api gives back response in XML format in the following example.

public function actionTest()
{
    $items = ['one', 'two', 'three' => ['a', 'b', 'c']];
    return $items;
}

This is the response:

<response>
  <item>one</item>
  <item>two</item>
   <three>
    <item>a</item>
    <item>b</item>
    <item>c</item>
   </three>
</response>

The only way I can get it to work is by adding this line to each of the controller behaviors. I have read the documentation which says I can initalize this on the module class so I do not need to do it in every controller. I do not know why it gives XML though. Also just in case the only way is to add it to my behaviors, do I have to write code to handle name, code, status, type, previous and code or does Yii provide yii\rest\Controller and yii\rest\ActiveController which automatically handle this. Clearly they are being output automatically when there is an error.

{"name":"Not Found"
 "message":"Page not found.",
 "code":0,
 "status":404
 "type":"yii\\web\\NotFoundHttpException"
 "previous":{"name":"Invalid Route","message":"Unable to resolve the request: api/home/",
 "code":0,"type":"yii\\base\\InvalidRouteException"
 }
}
like image 389
Lenny Carmi Avatar asked Aug 24 '15 07:08

Lenny Carmi


People also ask

Can Rest response XML?

Data types that REST API can return are as follows:XML. HTML.

What is REST API in yii2?

Using the Yii RESTful API framework, you implement an API endpoint in terms of a controller action, and you use a controller to organize the actions that implement the endpoints for a single type of resource. Resources are represented as data models which extend from the yii\base\Model class.


2 Answers

After three painful days, I have found the solutions. It is sometimes quite difficult to explain this problem when you are coming from a whole JSON world of ExpressJS and NodeJS. Logically what Yii2 does is perfectly fine, on the other hand 90% RESTful APIs expect the output to be in JSON hence you do not explicitly want to set request headers every time you make an API call.

Browsers by default add request headers as "Application/XML" hence what you see on screen is XML instead of JSON.

Yii2's content negotiator upon receipt of headers as application/xml formats your output in XML. If you make a same request using CURL or PostMan with headers as "Application/JSON" you will get the desired output.

If you wish to override this behaviour then just add the below function in your controller and include the following:-

use yii\web\Response; use yii\helpers\ArrayHelper;

public function behaviors()
  {
      return ArrayHelper::merge(parent::behaviors(), [
          [
              'class' => 'yii\filters\ContentNegotiator',
              'only' => ['view', 'index'],  // in a controller
              // if in a module, use the following IDs for user actions
              // 'only' => ['user/view', 'user/index']
              'formats' => [
                  'application/json' => Response::FORMAT_JSON,
              ],
              'languages' => [
                  'en',
                  'de',
              ],
          ],
      ]);
  }
like image 113
Viky293 Avatar answered Sep 28 '22 10:09

Viky293


In Yii2 applications default response type is XML (and I guess it's default for REST too). During HTTP connection both sides declares what type of data are able to send and/or receive. If this information is not passed to server default data type is send(even if you specified that it should be JSON in your app) to guarantee proper communication. If you want to receive JSON data you must add Accept: application/json header to your request. And probably you don't have to specify it in php code because Yii2 should deduct it from request headers.

You can find more explanation how it works here.

like image 42
Glapa Avatar answered Sep 28 '22 10:09

Glapa