RESTful API - это все о доступе и управлении ресурсами. Вы можете рассматривать ресурсы как модели в парадигме MVC.
Хотя нет ограничений в представлении ресурса, в Yii вы обычно представляли бы ресурсы в терминах объектов yii\base\Model
или его дочерних классов (например, yii\db\ActiveRecord) по следующим причинам:
yii\base\Model
реализует интерфейс yii\base\Arrayable, который позволяет вам настроить, как вы хотите предоставлять данные о ресурсах через API RESTful.yii\base\Model
поддерживает проверку ввода, что полезно, если ваши RESTful API должны поддерживать ввод данных.yii\db\ActiveRecord
обеспечивает мощную поддержку доступа к данным и манипуляций с БД, что делает его идеальным решением, если ваши данные о ресурсах хранятся в базах данных
В этом разделе мы в основном опишем, как класс ресурса, расширяющийся от yii\base\Model
(или его дочерних классов), может указывать, какие данные могут быть возвращены через API RESTful. Если класс ресурса не распространяется от yii\base\Model
, тогда будут возвращены все его открытые переменные-члены.
Поля
При включении ресурса в ответ RESTful API ресурс должен быть сериализован в строку. Yii разбивает этот процесс на два этапа. Во-первых, ресурс преобразуется в массив посредством yii\rest\Serializer
. Во-вторых, массив сериализуется в строку в запрошенном формате (например, JSON, XML) с помощью форм ответа. Первым шагом является то, что вы должны в основном сосредоточиться при разработке класса ресурсов.
Переопределяя fields()
или extraFields()
, вы можете указать, какие данные, называемые полями, в ресурсе могут быть помещены в его представление массива. Разница между этими двумя методами заключается в том, что первый определяет набор полей по умолчанию, который должен быть включен в представление массива, а второй указывает дополнительные поля, которые могут быть включены в массив, если конечный пользователь запрашивает их через параметр запроса expand. Например:
// returns all fields as declared in fields()
http://localhost/users
// only returns field id and email, provided they are declared in fields()
http://localhost/users?fields=id,email
// returns all fields in fields() and field profile if it is in extraFields()
http://localhost/users?expand=profile
// only returns field id, email and profile, provided they are in fields() and extraFields()
http://localhost/users?fields=id,email&expand=profile
Переопределение fields()
По умолчанию yii\base\Model::fields()
возвращает все атрибуты модели в виде полей, в то время как yii\db\ActiveRecord::fields()
возвращает только атрибуты, которые были заполнены из БД.
Вы можете переопределить fields()
для добавления, удаления, переименования или переопределения полей. Возвращаемое значение fields()
должно быть массивом. Ключами массива являются имена полей, а значениями массива являются соответствующие определения полей, которые могут быть либо именами свойств/атрибутов, либо анонимными функциями, возвращающими соответствующие значения полей. В особом случае, когда имя поля совпадает с именем определяющего атрибута, вы можете пропустить ключ массива. Например:
// explicitly list every field, best used when you want to make sure the changes
// in your DB table or model attributes do not cause your field changes (to keep API backward compatibility).
public function fields()
{
return [
// field name is the same as the attribute name
'id',
// field name is "email", the corresponding attribute name is "email_address"
'email' => 'email_address',
// field name is "name", its value is defined by a PHP callback
'name' => function ($model) {
return $model->first_name . ' ' . $model->last_name;
},
];
}
// filter out some fields, best used when you want to inherit the parent implementation
// and blacklist some sensitive fields.
public function fields()
{
$fields = parent::fields();
// remove fields that contain sensitive information
unset($fields['auth_key'], $fields['password_hash'], $fields['password_reset_token']);
return $fields;
}
Переопределение extraFields()
По умолчанию yii\base\Model::extraFields()
возвращает пустой массив, в то время как yii\db\ActiveRecord::extraFields()
возвращает имена отношений, которые были заполнены из базы данных.
Формат возвращаемых данных extraFields()
такой же, как у fields()
. Обычно extraFields()
в основном используется для указания полей, значения которых являются объектами. Например, учитывая следующее объявление поля:
public function fields()
{
return ['id', 'email'];
}
public function extraFields()
{
return ['profile'];
}
Запрос с http://localhost/users?fields=id,email&expand=profile
может возвращать следующие данные JSON:
[
{
"id": 100,
"email": "100@example.com",
"profile": {
"id": 100,
"age": 30,
}
},
...
]
Ссылки
HATEOAS, аббревиатура для Hypermedia как двигателя состояния приложения, способствует тому, что API RESTful должны возвращать информацию, которая позволяет клиентам обнаруживать действия, поддерживаемые для возвращаемых ресурсов. Ключ HATEOAS - вернуть набор гиперссылок с информацией о связи, когда данные ресурса обслуживаются API.
Ваши классы ресурсов могут поддерживать HATEOAS, реализуя интерфейс yii\web\Linkable
. Интерфейс содержит единственный метод getLinks()
, который должен возвращать список ссылок. Как правило, вы должны вернуть по крайней мере ссылку, представляющую URL-адрес, самому ресурсу. Например:
use yii\base\Model;
use yii\web\Link; // represents a link object as defined in JSON Hypermedia API Language.
use yii\web\Linkable;
use yii\helpers\Url;
class UserResource extends Model implements Linkable
{
public $id;
public $email;
//...
public function fields()
{
return ['id', 'email'];
}
public function extraFields()
{
return ['profile'];
}
public function getLinks()
{
return [
Link::REL_SELF => Url::to(['user/view', 'id' => $this->id], true),
'edit' => Url::to(['user/view', 'id' => $this->id], true),
'profile' => Url::to(['user/profile/view', 'id' => $this->id], true),
'index' => Url::to(['users'], true),
];
}
}
Когда в ответе возвращается объект UserResource
, он будет содержать элемент _links
, представляющий ссылки, связанные с пользователем, например:
{
"id": 100,
"email": "user@example.com",
// ...
"_links" => {
"self": {
"href": "https://example.com/users/100"
},
"edit": {
"href": "https://example.com/users/100"
},
"profile": {
"href": "https://example.com/users/profile/100"
},
"index": {
"href": "https://example.com/users"
}
}
}
Коллекции
Объекты ресурсов могут быть сгруппированы в коллекции. Каждая коллекция содержит список объектов ресурсов одного типа.
Хотя коллекции могут быть представлены как массивы, обычно более желательно представлять их в качестве поставщиков данных. Это связано с тем, что поставщики данных поддерживают сортировку и разбиение на страницы ресурсов, что обычно необходимо для возврата коллекций RESTful API. Например, следующее действие возвращает поставщика данных о ресурсах сообщения:
namespace app\controllers;
use yii\rest\Controller;
use yii\data\ActiveDataProvider;
use app\models\Post;
class PostController extends Controller
{
public function actionIndex()
{
return new ActiveDataProvider([
'query' => Post::find(),
]);
}
}
Когда поставщик данных отправляется в ответ RESTful API, yii\rest\Serializer выведет текущую страницу ресурсов и сериализует их как массив объектов ресурсов. Кроме того, yii\rest\Serializer также будет включать информацию о разбиении на страницы по следующим HTTP-заголовкам:
- X-Pagination-Total-Count: Общее количество ресурсов;
- X-Pagination-Page-Count: Количество страниц;
- X-Pagination-Current-Page: Текущая страница (на основе 1);
- X-Pagination-Per-Page: Количество ресурсов на каждой странице;
- Link: Набор навигационных ссылок, позволяющих клиенту перемещаться по страницам страниц.
0 комментариев