如何在 json 中强制 restful 响应?

How to force restful responses in json?

我想添加一些 api 到我的 Yii2 站点。 Api 必须仅在 json 中。我不想为每个请求设置 Accept: application/json headers。我可以在应用程序配置中设置 'response' => ['format' => \yii\web\Response::FORMAT_JSON] 但它会破坏所有页面。还有我的 api 函数 returns xml 中的数据。

我尝试将 rest\ActiveRecord 用于我的目的。也许我这样做是错误的。我想要什么。

让我的基于 Yii2 的网站有一些 api 通过 https://example.com/api/controller/action 访问。在项目中,我想查看包含我的控制器的文件夹 controllers/api。控制器必须使用基于标准 \yii\db\ActiveRecord 的模型。此外,控制器仅在 json body 中或作为部分 url 输入参数,并且仅在 json.

中输出数据

您可能需要在 return 之前或 beforeAction() 方法中的控制器操作中设置以下代码:

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

同样自 Yii 2.0.11 以来,有一个专用的 asJson() 方法来 return JSON 格式的响应:

return $this->asJson($array);

更优雅的解决方案是使用yii\filters\ContentNegotiator。 当缺少 Accept header 时,ContentNegotiator 假定它允许任何类型并以其 $formats 属性 中定义的第一种格式发送响应。如果请求的格式不在可接受的格式中,内容协商器将抛出 yii\web\NotAcceptableHttpException 并且应用程序将响应 http 状态 406 Not Acceptable.

您可以通过 behaviors() 方法将其添加到您的控制器中:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\ContentNegotiator',
            'formats' => [
                'application/json' => \yii\web\Response::FORMAT_JSON,
            ],
        ],
    ];
}

如果您的控制器扩展了 yii\rest\Controller,它已经在其行为中添加了 ContentNegotiator 过滤器。您只需要像这样限制允许的格式:

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

使用 ContentNegotiator 而不是在 beforeAction() 中明确强制使用 JSON 格式将允许在将来需要时更轻松地添加其他格式。