Spec-Zone.ru › Yii 2.0

Ресурсы

  1. Поля
  2. Ссылки
  3. Коллекции

RESTful API основаны на доступе и манипулировании ресурсами. Вы можете рассматривать ресурсы как модели в парадигме MVC.

Хотя нет ограничений на представление ресурса, в Yii вы обычно представляете ресурсы в виде объектов класса yii\base\Model или его дочерних классов (например, yii\db\ActiveRecord) по следующим причинам:

  • yii\base\Model реализует интерфейс yii\base\Arrayable, что позволяет настроить способ экспонирования данных ресурса через RESTful API.
  • yii\base\Model поддерживает валидацию ввода, что полезно, если ваши RESTful API должны поддерживать ввод данных.
  • yii\db\ActiveRecord предоставляет мощную поддержку доступа к данным БД и манипулирования ими, что делает его идеальным выбором, если данные вашего ресурса хранятся в базах данных.

В этом разделе мы в основном опишем, как класс ресурса, расширяющий yii\base\Model (или его дочерние классы), может указать, какие данные могут быть возвращены через RESTful API. Если класс ресурса не расширяет 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;
}

Предупреждение: Поскольку по умолчанию все атрибуты модели будут включены в результат API, вы должны проверить свои данные, чтобы убедиться, что они не содержат конфиденциальной информации. Если такая информация есть, вы должны переопределить fields() для их фильтрации. В приведенном выше примере мы выбрали отфильтровать auth_key, password_hash и password_reset_token.

Переопределение 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 as the Engine of Application State, предполагает, что RESTful API должны возвращать информацию, которая позволяет клиентам обнаруживать действия, поддерживаемые для возвращаемых ресурсов. Ключ HATEOAS заключается в возвращении набора гиперссылок с информацией о связи при предоставлении данных ресурсов API.

Ваши классы ресурсов могут поддерживать HATEOAS, реализуя интерфейс yii\web\Linkable. Интерфейс содержит единственный метод getLinks(), который должен возвращать список ссылок. Как правило, вы должны вернуть по крайней мере ссылку self, представляющую 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: Набор навигационных ссылок, позволяющий клиенту просматривать ресурсы по страницам.

Пример можно найти в разделе Быстрый старт.

© 2008–2017 by Yii Software LLC
Licensed under the three clause BSD license.
http://www.yiiframework.com/doc-2.0/guide-rest-resources.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API