При обработке запроса RESTful API приложение обычно выполняет следующие шаги, связанные с форматированием ответа:
- Определите различные факторы, которые могут повлиять на формат ответа, например, тип носителя, язык, версия и т.д. Этот процесс также известен как согласование содержимого.
- Преобразуйте объекты ресурсов в массивы с помощью yii\rest\Serializer.
- Преобразование массивов в строку в формате, определенном на этапе согласования содержимого. Это выполняется с помощью форм ответов, зарегистрированных в свойстве
formatters
компонента приложения ответа.
Согласование содержимого
Yii поддерживает согласование содержимого через фильтр yii\filters\ContentNegotiator
. Класс базового контроллера API RESTful yii\rest\Controller
снабжен этим фильтром под именем contentNegotiator
. Фильтр обеспечивает согласование формата ответа, а также согласование языка. Например, если запрос API RESTful содержит следующий заголовок:
Accept: application/json; q=1.0, */*; q=0.1
Он получит ответ в формате JSON, например:
$ curl -i -H "Accept: application/json; q=1.0, */*; q=0.1" "http://localhost/users"
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
[
{
"id": 1,
...
},
{
"id": 2,
...
},
...
]
За сценой до выполнения действия контроллера RESTful API фильтр yii\filters\ContentNegotiator
проверяет заголовок Accept HTTP в запросе и устанавливает формат ответа в виде 'json'. После выполнения действия и возврата результирующего ресурсного объекта или коллекции yii\rest\Serializer преобразует результат в массив. И, наконец, yii\web\JsonResponseFormatter
будет сериализовывать массив в строку JSON и включать его в тело ответа.
По умолчанию RESTful API поддерживают форматы JSON и XML. Чтобы поддерживать новый формат, вы должны настроить свойство formats
фильтра contentNegotiator
, например, следующее в ваших классах контроллера API:
use yii\web\Response;
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_HTML;
return $behaviors;
}
Ключами свойства formats
являются поддерживаемые типы MIME, а значения - соответствующие имена формата ответа, которые должны поддерживаться в формате yii\web\Response::$formatters
.
Сериализация данных
Как мы описали выше, yii\rest\Serializer
является центральной частью, ответственной за преобразование объектов ресурсов или коллекций в массивы. Он распознает объекты, реализующие yii\base\Arrayable
, а также yii\data\DataProviderInterface
. Первый из них реализуется в основном ресурсными объектами, а второй - коллекциями ресурсов.
Сериализатор можно настроить, установив свойство yii\rest\Controller::$serializer
с массивом конфигурации. Например, иногда вы можете помочь упростить работу по разработке клиента, включив информацию о разбиении на страницы непосредственно в теле ответа. Для этого настройте свойство yii\rest\Serializer::$collectionEnvelope
следующим образом:
use yii\rest\ActiveController;
class UserController extends ActiveController
{
public $modelClass = 'app\models\User';
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
}
Вы можете получить следующий ответ для запроса http://localhost/users
:
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"items": [
{
"id": 1,
...
},
{
"id": 2,
...
},
...
],
"_links": {
"self": {
"href": "http://localhost/users?page=1"
},
"next": {
"href": "http://localhost/users?page=2"
},
"last": {
"href": "http://localhost/users?page=50"
}
},
"_meta": {
"totalCount": 1000,
"pageCount": 50,
"currentPage": 1,
"perPage": 20
}
}
Управление выходом JSON
Ответ JSON генерируется классом JsonResponseFormatter
, который будет использовать помощник JSON внутри. Этот форматтер может быть сконфигурирован с различными опциями, такими как, например, параметр $prettyPrint
, который полезен при разработке для более читабельных ответов, или $encodeOptions
для управления выходом JSON-кодировки.
Форматирование можно настроить в свойстве formatters
компонента приложения ответа в конфигурации приложения, например:
'response' => [
// ...
'formatters' => [
\yii\web\Response::FORMAT_JSON => [
'class' => 'yii\web\JsonResponseFormatter',
'prettyPrint' => YII_DEBUG, // use "pretty" output in debug mode
'encodeOptions' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
// ...
],
],
],
При возврате данных из базы данных с использованием уровня базы данных DAO все данные будут представлены в виде строк, что не всегда является ожидаемым результатом, особенно числовые значения должны быть представлены в виде чисел в JSON. При использовании уровня ActiveRecord для извлечения данных из базы данных значения числовых столбцов будут преобразованы в целые числа, когда данные будут извлечены из базы данных в файле yii\db\ActiveRecord::populateRecord()
.
0 комментариев