RESTful API интерфейсы предназначены для доступа и управления *ресурсами*. Вы можете представлять ресурсы как
[модели](structure-models.md) в архитектуре[MVC](http://ru.wikipedia.org/wiki/Model-View-Controller).
RESTful API строятся вокруг доступа к *ресурсам* и управления ими. Вы можете думать о ресурсах как
о [моделях](structure-models.md) из[MVC](http://ru.wikipedia.org/wiki/Model-View-Controller).
Хотя в Yii нет никаких ограничений в том как представить ресурс, здесь вы можете представлять ресурсы
как объект наследующий свойства и методы [[yii\base\Model]] или дочерних классов (например [[yii\db\ActiveRecord]]), потому как:
Хотя не существует никаких ограничений на то, как представить ресурс, в Yii ресурсы обычно представляются
как объекты [[yii\base\Model]] или дочерних классов (например [[yii\db\ActiveRecord]]), потому как:
*[[yii\base\Model]] реализует [[yii\base\Arrayable]] интерфейс, настраиваемый как вам удобно, для представления
данных через RESTful API интерфейс.
*[[yii\base\Model]] поддерживает [валидацию](input-validation.md), что полезно для RESTful API
реализующего ввод данных.
*[[yii\db\ActiveRecord]] реализует мощный функционал для работы с БД, будет полезным если данные ресурса хранятся в поддерживаемых БД.
*[[yii\base\Model]] реализует интерфейс [[yii\base\Arrayable]], который позволяет задать способ отдачи данных
ресурса через RESTful API.
*[[yii\base\Model]] поддерживает [валидацию](input-validation.md), что полезно для RESTful API реализующего ввод данных.
*[[yii\db\ActiveRecord]] даёт мощную поддержку работы с БД, что актуально если данные ресурса хранятся в ней.
В этом разделе, мы опишем как использовать методы наследуемые вашим класом ресурсов от [[yii\base\Model]] (или дочерних классов) необходимые RESTful API.
> Если класс ресурса не наследуется от [[yii\base\Model]], то будут возвращены все public поля.
В этом разделе, мы сосредоточимся на том, как при помощи класса ресурса, наследуемого от [[yii\base\Model]]
(или дочерних классов) задать какие данные будут возвращаться RESTful API. Если класс ресурса не наследуется от
[[yii\base\Model]], возвращаются всего его public свойства.
## Поля <a name="fields"></a>
Когда ресурс включается в ответ RESTful API, необходимо представить(сеарилизовать) ресурс как строку.
Yii разбивает процесс сеарилизации на два шага. На первом шаге, ресурс конвертируется в массив [[yii\rest\Serializer]].
На втором шаге, массив сеарилизуется в строку в требуемом формате (JSON, XML) при помощи
[[yii\web\ResponseFormatterInterface|интерфейса для форматирования ответа]]. Это сделано для того чтобы при разработке вы могли сосредоточится на разработке класса ресурсов.
Когда ресурс включается в ответ RESTful API, необходимо сеарилизовать его в строку. Yii разбивает этот процесс на два этапа.
Сначала ресурс конвертируется в массив при помощи [[yii\rest\Serializer]]. На втором этапе массив сеарилизуется в строку
заданного формата (например, JSON или XML) при помощи [[yii\web\ResponseFormatterInterface|форматтера ответа]].
Именно на этом стоит сосредоточится при разработке класса ресурса.
При переопределении методов [[yii\base\Model::fields()|fields()]] и/или [[yii\base\Model::extraFields()|extraFields()]],
вы можете указать какие данные будут отображаться при представлении в виде массива.
Разница между этими двумя методами в том, что первый определяет стандартный набор полей которые будут включены в представлении массивом, а второй
определяет дополнительные поля, которые могут быть включены в массив если запрос пользователя к ресурсу использует дополнительные параметры.
Например:
Вы можете указать какие данные включать в представление ресурса в виде массива путём переопределения методов
[[yii\base\Model::fields()|fields()]] и/или [[yii\base\Model::extraFields()|extraFields()]]. Разница между ними в том,
что первый определяет набор полей которые всегда будут включены в массив, а второй определяет дополнительные поля, которые
пользователь может запросить через параметр `expand`:
По умолчанию, [[yii\base\Model::fields()]] вернёт все атрибуты модели как поля, пока что
[[yii\db\ActiveRecord::fields()]] возвращает только те атрибуты которые были объявлены в схеме БД.
По умолчанию, [[yii\base\Model::fields()]] возвращает все атрибуты модели как поля, а
[[yii\db\ActiveRecord::fields()]] возвращает только те атрибуты, которые были объявлены в схеме БД.
Вы можете переопределить `fields()` для того, чтобы добавить, удалить, переименовать или переобъявить поля. Значение,
возвращаемое `fields()`, должно быть массивом. Его ключи это имена полей, и значения могут быть либо именами
свойств/атрибутов, либо анонимными функциями, которые возвращают значение соответствующих полей. Если имя атрибута такое же,
как ключ массива вы можете опустить значение:
Вы можете переопределить `fields()` при этом добавить, удалить, переименовать или переобъявить поля. Возвращаемое значение `fields()`
должно быть массивом. Ключи массива это имена полей, и значения массива могут быть именами свойств/атрибутов или анонимных функций, возвращающих соответствующее значение полей.
Если имя атрибута такое же, как ключ массива вы можете не заполнять значение. Например:
```php
// явное перечисление всех атрибутов, лучше всего использовать когда вы хотите убедиться что изменение
// таблицы БД или атрибутов модели не повлияет на изменение полей в представлении для API (для поддержки обратной совместимости с API).
// явное перечисление всех атрибутов лучше всего использовать когда вы хотите быть уверенным что изменение
// таблицы БД или атрибутов модели не повлияет на изменение полей, отдаваемых API (что важно для поддержки обратной
// совместимости API).
publicfunctionfields()
{
return[
// название поля совпадает с названием атрибута
'id',
// ключ массива "email", соответствует значению атрибута "email_address"
// имя поля "email", атрибут "email_address"
'email'=>'email_address',
// ключ массива "name", это PHP callback функция возвращающая значение
// имя поля "name", значение определяется callback-ом PHP
'name'=>function(){
return$this->first_name.' '.$this->last_name;
},
];
}
// Для фильтрации полей лучше всего использовать, поля наследуемые от родительского класса
// и blacklist для не безопасных полей.
// отбрасываем некоторые поля. Лучше всего использовать в случае наследования
publicfunctionfields()
{
$fields=parent::fields();
...
...
@@ -83,18 +84,17 @@ public function fields()
}
```
> Внимание: По умолчанию все атрибуты модели будут включены в представление для API, вы должны
> убедиться что не безопасные данные, не попадут в представление. Если в модели есть не безопасные поля,
> вы должны переопределить метод `fields()` для их фильтрации. В приведённом примере
> мы удаляем из представления `auth_key`, `password_hash` и `password_reset_token`.
> Внимание: По умолчанию все атрибуты модели будут включены в ответы API. Вы должны убедиться в том, что отдаются
> только безопасные данные. В противном случае для исключения небезопасных полей необходимо переопределить метод
> `fields()`. В приведённом выше примере мы исключаем `auth_key`, `password_hash` и `password_reset_token`.
По умолчанию, [[yii\base\Model::extraFields()]] ничего не возвращает, а [[yii\db\ActiveRecord::extraFields()]]
возвращает названия отношений объявленных в ДБ.
возвращает названия заданных в БД связей.
Формат вовзращаемызх данных `extraFields()` такой же как`fields()`. Как правило, `extraFields()`
Формат вовзращаемызх `extraFields()` данных такой же как у`fields()`. Как правило, `extraFields()`
используется для указания полей, значения которых являются объектами. Например учитывая следующее объявление полей
```php
...
...
@@ -126,14 +126,16 @@ public function extraFields()
```
## Связи <a name="links"></a>
## Ссылки <a name="links"></a>
Согласно [HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), расшифровывающемуся как Hypermedia as the Engine of Application State,
RESTful API должны возвращать достаточно информации для того, чтобы клиенты могли определить возможные действия над ресурсами.
Ключевой момент HATEOAS заключается том, чтобы возвращать вместе с данными набора гиперссылок, указывающих на связанную
с ресурсом информацию.
[HATEOAS](http://en.wikipedia.org/wiki/HATEOAS), аббревиатура для Hypermedia as the Engine of Application State,
необходим для того чтобы RESTful API, мог отобразить информацию которая позволяет клиентам просматривать возможности, поддерживаемые ресурсом. Ключ HATEOAS возвращает список ссылок с
информацией о параметрах доступных в методах API.
Ваши классы ресурсов могу поддерживать HATEOAS реализуя [[yii\web\Linkable]] интерфейс. Интерфейс
реализует один метод [[yii\web\Linkable::getLinks()|getLinks()]] который возвращает список [[yii\web\Link|links]].
Вы должны вернуть существующий URL на метод ресурса. Например:
Поддержку HATEOAS в ваши классы ресурсов можно добавить реализовав интерфейс [[yii\web\Linkable]]. Этот интерфейс
содержит единственный метод [[yii\web\Linkable::getLinks()|getLinks()]], который возвращает список [[yii\web\Link|ссылок]].
Обычно вы должны вернуть хотя бы ссылку `self` с URL самого ресурса:
```php
useyii\db\ActiveRecord;
...
...
@@ -152,8 +154,7 @@ class User extends ActiveRecord implements Linkable
}
```
При отправке ответа объект `User` будет содержать поле `_links` содержащий ссылки связанные с объектом `User`.
Например:
При отправке ответа объект `User` содержит поле `_links`, значение которого — ссылки, связанные с объектом:
```
{
"id": 100,
...
...
@@ -168,11 +169,12 @@ class User extends ActiveRecord implements Linkable
## Коллекции <a name="collections"></a>
Объекты ресурсов могут группироваться в *коллекции*. Каждая коллекция включает список объектов ресурсов одного типа.
Объекты ресурсов могут группироваться в *коллекции*. Каждая коллекция содержит список объектов ресурсов одного типа.
Так как коллекции представляются в виде массива, их удобнее использовать как [проводник данных](output-data-providers.md).
Так как проводник данных поддерживает операции сортировки, разбиения на страницы это удобно использовать для RESTful API.
Например следующей метод возвращает проводник данных о почтовом ресурсе:
Несмотря на то, что коллекции можно представить в виде массива, удобнее использовать
[провайдеры данных](output-data-providers.md) так как они поддерживают сортировку и постраничную разбивку.
Для RESTful APIs, которые работают с коллекциями, данные возможности используются довольно часто. Например, следующее
действие контроллера возвращает провайдер данных для ресурса постов:
```php
namespaceapp\controllers;
...
...
@@ -192,13 +194,13 @@ class PostController extends Controller
}
```
При отправке ответа RESTful API, [[yii\rest\Serializer]] добавит текущую страницу ресурсов и сериализует все объекты ресурсов.
Кроме того, [[yii\rest\Serializer]] добавит HTTP заголовки содержащие информацию о нумерации страниц:
При отправке ответа RESTful API, [[yii\rest\Serializer]] сериализует массив объектов ресурсов для текущей страницы.
Кроме того, он добавит HTTP заголовки, содержащие информацию о страницах:
*`X-Pagination-Total-Count`: Количество ресурсов;
*`X-Pagination-Page-Count`: Количество страниц ресурсов;
*`X-Pagination-Current-Page`: Текущая страница (начинается с 1);
*`X-Pagination-Per-Page`: Количество ресурсов отображаемых на 1 странице;
*`Link`: Набор ссылок позволяющий клиенту пройти все ресурсы, страница за страницей.
*`X-Pagination-Total-Count`: общее количество ресурсов;
*`X-Pagination-Page-Count`: количество страниц;
*`X-Pagination-Current-Page`: текущая страница (начиная с 1);
*`X-Pagination-Per-Page`: количество ресурсов на страницу;
*`Link`: набор ссылок, позволяющий клиенту пройти все страницы ресурсов.
Примеры вы можете найти в разделе [Быстрый старт](rest-quick-start.md#trying-it-out).
Примеры вы можете найти в разделе «[быстрый старт](rest-quick-start.md#trying-it-out)».