12

The problem is that responses from RESTful server in Yii2 come back as XML, and I need them to be in JSON format.

I was following the guide from Yii2, the controller looks the same, the model is kind of different, it is connected to a database (the model was previously copied from a default model in an advanced template), and web config is also the same like the guide.

Just to clarify any doubts, here is the code:

UserController.php

<?php
namespace app\controllers;

use yii\rest\ActiveController;

class UserController extends ActiveController
{
    public $modelClass = 'app\models\User';
}

web.php ($config)

$config = [
    'id' => 'basic',
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log'],
    'components' => [
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'WgkzlqvStTfGXY-ToFlQIJRDMX4LUQtY',
            'parsers'=>[
                'application/json'=>'yii\web\JsonParser'
            ]
        ],
        'cache' => [
            'class' => 'yii\caching\FileCache',
        ],
        'user' => [
            'identityClass' => 'app\models\User',
            'enableAutoLogin' => true,
        ],
        'urlManager' => [
            'enablePrettyUrl' => true,
            'enableStrictParsing' => true,
            'showScriptName' => false,
            'rules' => [
                ['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
            ],
        ],
        'errorHandler' => [
            'errorAction' => 'site/error',
        ],
        'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            // send all mails to a file by default. You have to set
            // 'useFileTransport' to false and configure a transport
            // for the mailer to send real emails.
            'useFileTransport' => true,
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'db' => require(__DIR__ . '/db.php'),
    ],
    'params' => $params,
];

I tried settings in the config component:

response=>[
    'format'=>yii\web\Response::FORMAT_JSON
]

...but it still responds with XML. What do I do to make it respond with JSON?

3 Answers 3

12

You can set it initially on call like below:

\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

For example:

public function actionView($id) {\
  Yii::$app - > response - > format = \yii\ web\ Response::FORMAT_JSON;
  $user = \app\ models\ User::find($id);
  return $user;
}

You can also use ContentNegotiator filter in your class behaviors like below:

/**
 * @inheritdoc
 */
public function behaviors() {
  return [
    [
      'class' => \yii\ filters\ ContentNegotiator::className(),
      'only' => ['index', 'view'],
      'formats' => [
        'application/json' => \yii\ web\ Response::FORMAT_JSON,
      ],
    ],
  ];
}
Sign up to request clarification or add additional context in comments.

3 Comments

But is there a way to set this globally? Rather than adding this in each controller?
i tried your method through controllers and it works, but i tried what your referenced post shows and it doesn't work, it would still response as xml, you can see the code here: pastebin.com/PawqVx7X
1

Just set the Response's format in your application configuration:

'components' => [
    ... // config
    'response' => [
        'format' => \yii\web\Response::FORMAT_JSON
    ],
    ... // config
]

Comments

0

Another way would be to derive the custom response class and set format based on data type.

class Response extends \yii\web\Response
{
    protected function prepare()
    {
        if (is_object($this->data) || is_array($this->data)) {
            $this->format = self::FORMAT_JSON;
        }
        return parent::prepare();
    }
}

Then register this type in the configuration file.

'response' => [
    'class' => 'app\components\Response',
]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.