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