I have defined a custom response class and was trying to use it in a module.
In the controller action i return an array of results, but the custom response class isn't used.
Instead, the class used is the default yii\web\Response
My implementation
The module configuration in config/web.php:
'mymodule' => [
'class' => 'app\modules\mymod\Mymod',
'components' => [
'response' => [
'class' => 'app\modules\mymod\components\apiResponse\ApiResponse',
'format' => yii\web\Response::FORMAT_JSON,
'charset' => 'UTF-8',
],
],
],
In the controller i edited the behaviors method:
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['contentNegotiator'] = [
'class' => 'yii\filters\ContentNegotiator',
'response' => $this->module->get('response'),
'formats' => [ //supported formats
'application/json' => \yii\web\Response::FORMAT_JSON,
],
];
return $behaviors;
}
In the action if i do:
public function actionIndex() {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$dataList = [
['id' => 1, 'name' => 'John', 'surname' => 'Davis'],
['id' => 2, 'name' => 'Marie', 'surname' => 'Baker'],
['id' => 3, 'name' => 'Albert', 'surname' => 'Bale'],
];
return $dataList;
}
I get this result (as expected from yii\web\Response):
[
{
"id": 1,
"name": "John",
"surname": "Davis"
},
{
"id": 2,
"name": "Marie",
"surname": "Baker"
},
{
"id": 3,
"name": "Albert",
"surname": "Bale"
}
]
But if i change the action to this:
$dataList = [
['id' => 1, 'name' => 'John', 'surname' => 'Davis'],
['id' => 2, 'name' => 'Marie', 'surname' => 'Baker'],
['id' => 3, 'name' => 'Albert', 'surname' => 'Bale'],
];
//return $dataList;
$resp = $this->module->get('response'); //getting the response component from the module configuration
$resp->data = $dataList;
return $resp;
Then i get the expected result, which is this:
{
"status": {
"response_code": 0,
"response_message": "OK",
"response_extra": null
},
"data": [
{
"id": 1,
"name": "John",
"surname": "Davis"
},
{
"id": 2,
"name": "Marie",
"surname": "Baker"
},
{
"id": 3,
"name": "Albert",
"surname": "Bale"
}
]}
It seems the behaviors i defined aren't doing anything.
What do i need to do to just return the array in the action and the custom response component is used?
Thanks in advance
Controllers are part of the MVC architecture. They are objects of classes extending from yii\base\Controller and are responsible for processing requests and generating responses.
You can send HTTP headers by manipulating the header collection in the response component. For example, $headers = Yii::$app->response->headers; // add a Pragma header. Existing Pragma headers will NOT be overwritten.
yii\base\Module
does not have response component, so your configuration will not work.
Instead of adding response
component into your module You sould change Yii::$app->response
inside MyMod::init()
function.
If you want completely replace Yii::$app->response
by your own component:
public function init()
{
parent::init();
\Yii::configure(\Yii::$app, [
'components' => [
'response' => [
'class' => 'app\modules\mymod\components\apiResponse\ApiResponse',
'format' => yii\web\Response::FORMAT_JSON,
'charset' => 'UTF-8',
],
]
]);
}
But i think that this is a bad idea to completely replace Response component of parent application in a module. The better way is modify Response behavior for your needs. For example You can use EVENT_BEFORE_SEND
and build your own data structure in response:
public function init()
{
parent::init();
// you can use ContentNegotiator at the level of module
// and remove this behavior declaration from controllers
\Yii::configure($this, [
'as contentNegotiator' => [
'class' => 'yii\filters\ContentNegotiator',
// if in a module, use the following IDs for user actions
// 'only' => ['user/view', 'user/index']
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
]);
// you can daclare handler as function in you module and pass it as parameter here
\Yii::$app->response->on(Response::EVENT_BEFORE_SEND, function ($event) {
$response = $event->sender;
// here you can get and modify everything in current response
// (data, headers, http status etc.)
$response->data = [
'status' => 'Okay',
'data' => $response->data
];
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With