Как заставить restful ответы в json?

#yii2

#yii2

Вопрос:

Я хочу добавить некоторый api на свой сайт Yii2. Api должен быть только в формате json. Я не хочу устанавливать Accept: application/json заголовки для каждого запроса. Я могу настроить 'response' => ['format' => yiiwebResponse::FORMAT_JSON] конфигурацию приложения, но это разбивает все страницы. Также моя функция api возвращает данные в формате xml.

Я пытался использовать restActiveRecord в своих целях. Может быть, я делаю это неправильно. То, что я хочу.

Чтобы иметь доступ к моему сайту на базе Yii2 с некоторым API https://example.com/api/controller/action . В проекте я хочу увидеть папку controllers/api , в которой содержатся мои контроллеры. Контроллеры должны использовать стандартные yiidbActiveRecord модели. Кроме того, контроллеры вводят параметры только в теле json или как часть url и выводят данные только в json.

Ответ №1:

Возможно, вам потребуется установить следующий код в action контроллера где-нибудь перед return или в методе beforeAction():

 Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;
 

также, начиная с Yii 2.0.11, существует специальный метод asJson() для возврата ответа в формате JSON:

 return $this->asJson($array);
 

Ответ №2:

Более элегантным решением является использование yiifiltersContentNegotiator . Когда Accept заголовок отсутствует ContentNegotiator , предполагается, что он разрешает любой тип и отправляет ответ в первом формате, определенном в его $formats свойстве. Если запрошенный формат не входит в число принятых форматов , средство согласования содержимого выдаст yiiwebNotAcceptableHttpException запрос , и приложение ответит статусом http 406 Not Acceptable .

Вы можете добавить его в свой контроллер следующим behaviors() образом:

 public function behaviors()
{
    return [
        [
            'class' => 'yiifiltersContentNegotiator',
            'formats' => [
                'application/json' => yiiwebResponse::FORMAT_JSON,
            ],
        ],
    ];
}
 

Если ваш контроллер расширяется yiirestController , у него уже есть ContentNegotiator фильтр, добавленный к его поведению. Вам нужно только ограничить разрешенные форматы, подобные этому:

 public function behaviors()
{
    $behaviors = parent::behaviors();
    $behaviors['contentNegotiator']['formats'] = [
        'application/json' => yiiwebResponse::FORMAT_JSON,
    ];
    return $behaviors;
}
 

Использование ContentNegotiator вместо явного принудительного JSON ввода формата beforeAction() позволит упростить добавление других форматов, если они понадобятся в будущем.