Custom Response object initialized in Content Negotiation configuration array not called in Controller


(manesvenom) #1

Hi,

I want to create a custom response object for the RESTful API. Since the application supports both HTML and JSON call. I don’t want to set the Response component in web.php to affect the whole application.

If I put the following config to web.php, it will affect all requests even that is HTML call
‘response’ => [
‘format’ => yii\web\Response::FORMAT_JSON,
‘charset’ => ‘UTF-8’,
‘class’ => ‘\app\components\ApiResponse’,
‘on beforeSend’ => function($event){
$response = $event->sender;
if($response->data !==null){
$return = ($response->statusCode == 200 ? $response->data: $response->data[‘message’]);
$response->data = [
‘success’ =>($response->statusCode === 200),
‘status’ => $response->statusCode,
‘response’ => $return
];
}
}
]

Refer to the doc https://www.yiiframework.com/doc/guide/2.0/en/rest-response-formatting , in the Content Negotiation filter configuration array, there is a response property that can be assigned to a custom response object. I tried to rename the response component in web.php to responseapi, then the application would not use this response component for normal http request.

web.php
‘responseapi’ => [
‘format’ => yii\web\Response::FORMAT_JSON,
‘charset’ => ‘UTF-8’,
‘class’ => ‘\app\components\ApiResponse’,
‘on beforeSend’ => function($event){
$response = $event->sender;
if($response->data !==null){
$return = ($response->statusCode == 200 ? $response->data: $response->data[‘message’]);
$response->data = [
‘success’ =>($response->statusCode === 200),
‘status’ => $response->statusCode,
‘response’ => $return
];
}
}
]

In the controller, I tried to declare the contentNegoitator configuration array as below.
public function behaviors()
{

    $behaviors = parent::behaviors();

    $behaviors['contentNegotiator'] = [

            'class' => 'yii\filters\ContentNegotiator',                
            'formats' => [

                'application/json' => Response::FORMAT_JSON,

            ],
            'response' => Yii::$app->responseapi  //supposed that is the response component declared in web.php
            

    ];
 return $behaviors;

}

When the action is called, the response component declared in Content Negoitator is initialized.

However the response component returned from the handleRequest in Application.php is not the custom response component.

Is there any sample to explain how to use the response object inside the Content Negotiator for specific controller only.

Cheers,

Venom