Настройка ETag кэширования в REST API

Всё что касается построения API
Ответить
novi40k
Сообщения: 7
Зарегистрирован: 2018.04.12, 15:46

Настройка ETag кэширования в REST API

Сообщение novi40k » 2018.04.12, 17:53

Всем добрый день.

Нужна помощь новичку) Помогите настроить кэширование!

Есть бэк Yii2 REST API, фронт Vue.js, бд Oracle, контроллеры, модели... наследуемость контроллеров Test_apiController -> ApiController -> yii\rest\ActiveController.
Нужно сделать кэширование. Выбрал вариант на стороне клиента - ETag (т.к. нет возможности добавить столбец в таблицу и отслеживать Last Modified).

При запросе GET http://test2.ru/api/test_api/index вываливается Exception:

Код: Выделить всё

yii\base\InvalidArgumentException: Response content must not be an array. in /web/www/vendor/yiisoft/yii2/web/Response.php:1058
Stack trace:
#0 /web/www/vendor/yiisoft/yii2/web/Response.php(337): yii\web\Response->prepare()
#1 /web/www/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Response->send()
#2 /web/www/web/index.php(12): yii\base\Application->run()
#3 {main}
Получается передаётся массив, а не JSON. Спрашивается какого? Если в конфиге строго прописано:

Код: Выделить всё

'response' => [
			'formatters' => [
				\yii\web\Response::FORMAT_JSON => [
					'class' => 'yii\web\JsonResponseFormatter',
					'prettyPrint' => pretty, // YII_DEBUG
					'encodeOptions' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
					//'contentType' => \yii\web\JsonResponseFormatter::CONTENT_TYPE_HAL_JSON, 
				],
			],
		],
Что самое интересное это ETag передаётся (подглядел в Postman):

Код: Выделить всё

Cache-Control →public, max-age=0, must-revalidate
Connection →close
Content-Type →text/html; charset=UTF-8
Date →Thu, 12 Apr 2018 14:33:41 GMT
Etag →"2AafhPD8wNhLaZJjUO645y9is1I"
Link →<http://test2.ru/api/test_api?page=1>; rel=self, <http://test2.ru/api/test_api?page=2>; rel=next, <http://test2.ru/api/test_api?page=3>; rel=last
Server →Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_auth_kerb/5 mod_fcgid/2 PHP/7.0.9
Transfer-Encoding →chunked
X-Debug-Duration →40
X-Debug-Link →/debug/default/view?tag=5acf6e45a2aee
X-Debug-Tag →5acf6e45a2aee
X-Pagination-Current-Page →1
X-Pagination-Page-Count →3
X-Pagination-Per-Page →20
X-Pagination-Total-Count →52
X-Powered-By →PHP/7.0.9
В чем ошибка? Может я не так подключаю behaviors в Test_apiController? Стоит его перенести в ApiController?

ПРИЛОЖЕНИЕ:
Код Test_apiController.php

Код: Выделить всё

<?php

namespace app\controllers\api;

use Yii;
use yii\rest\ActiveController;
use yii\base\Model;
use yii\helpers\Url;
use yii\web\ServerErrorHttpException;
use yii\data\ActiveDataProvider;
use yii\helpers\ArrayHelper;
use app\models\api\TEST_API;
use yii\filters\HttpCache;
use yii\base\Behavior;
 
class Test_apiController extends \app\controllers\api\ApiController
{
		
    public $modelClass = 'app\models\api\TEST_API';
	
	public function behaviors()
	{
		return [
			[
				'class' => 'yii\filters\HttpCache',
				'only' => ['index'],
				'cacheControlHeader' => 'public, max-age=0, must-revalidate',
				'etagSeed' => function ($action, $params) {
					$test = TEST_API::find();
					return $test;
				},
			],
		];
	}
}

novi40k
Сообщения: 7
Зарегистрирован: 2018.04.12, 15:46

Re: Настройка ETag кэширования в REST API

Сообщение novi40k » 2018.04.17, 16:12

РЕШЕНО: изменил behaviors, добавил contentNegotiator

Код: Выделить всё

public function behaviors() 
	{
		return [
			'etagSeed' => [
				'class' => 'yii\filters\HttpCache',
				'only' => ['index'], 
				'cacheControlHeader' => 'public, max-age=0, must-revalidate',
				'etagSeed' => function ($action, $params) {
					$tag = $this->modelClass::find();
					return $tag;
				},
			],
			'contentNegotiator' => [
				'class' => ContentNegotiator::className(),
				'formats' => [
					'application/json' => Response::FORMAT_JSON,
				],
			],
		];
	}

Ответить