23 окт. 2015 г., 10:47:21 Yii2 rest api 0 Комментариев
Проблема "невозможности" указать формат ответа у ошибок, которые, к примеру были вызваны вне контроллера и не могут быть "пропущены" через yii\filters\ContentNegotiator
имеет место быть, т.к. в сети по этому поводу 0, а в тех болванках, что предназначены для демонстрации возможностей Yii2 в плане REST из коробки, все решение данного вопроса сводилось к тому, чтобы просто явно указать формат ответа в yii\web\Response
, что вообще, я считаю, костыль, т.к. весь смысл отдачи ответа в разных форматах сразу продает.
Решение оказалось очень простым, просто нужно внимательно читать документацию к классам, а не бегать глазами по ней. В классе yii\filters\ContentNegotiator
черным по белому написано:
* The following code shows how you can use ContentNegotiator as a bootstrapping component. Note that in this case, * the content negotiation applies to the whole application. * * ```php * // in application configuration * use yii\web\Response; * * return [ * 'bootstrap' => [ * [ * 'class' => 'yii\filters\ContentNegotiator', * 'formats' => [ * 'application/json' => Response::FORMAT_JSON, * 'application/xml' => Response::FORMAT_XML, * ], * 'languages' => [ * 'en', * 'de', * ], * ], * ], * ]; * ```
, что в переводе: "если тебе, парниш, нужен ровный, пацанский REST - пихай меня в boostrap своего приложения, и все будет шикарно". Именно так, нам и нужно сделать, но перед этим не забудьте убрать ContentNegotiator из списка поведений в контроллере.
Далее, есть еще такой момент. Дефолтный yii\web\ErrorHandler
, я считаю, нужно напильником немного. Данный ErrorHandler заменяет код ответа на 500, если исключение не имеет ничего общего с yii\web\HttpException
, т.е. экземпляром класса, но, и кроме этого, в случае запроса не указанного или неизвестного формата ответа кидается исключение yii\web\UnsupportedMediaTypeHttpException
, которое отдает ответ в HTML формата. Лично я "заглушил" контент ответа на это исключение и вернул только код ответа в заголовке, т.к. раз мы не знает такой формат, то и нечего что-то отдавать. Это все можно сделать так:
namespace app\components\rest; use Yii; use yii\web\Response; use yii\web\UnsupportedMediaTypeHttpException; /** * @inheritdoc */ class ErrorHandler extends \yii\web\ErrorHandler { /** * @inheridoc */ protected function renderException($exception) { if (Yii::$app->has('response')) { $response = Yii::$app->getResponse(); // reset parameters of response to avoid interference with partially created response data // in case the error occurred while sending the response. $response->isSent = false; $response->stream = null; $response->data = null; $response->content = null; } else { $response = new Response(); } if ($exception instanceof UnsupportedMediaTypeHttpException) { $response->data = ''; } else { $response->data = $this->convertExceptionToArray($exception); } $response->setStatusCode($exception->statusCode); $response->send(); } }
Теперь все равно и по пацански. На районе оценят.
Комментарии [0]
Новый комментарий