Классы контроллеров
В этом разделе описаны все PHP классы, которые используются в WP API. Они делятся на два типа: Классы инфраструктуры и Классы контроллеров (маршрутов, конечных точек, ресурсов).
Общие сведения
В WP API используется принцип Model-View-Controller — это стандартная модель в разработке приложений. Суть этой модели в том, что логика приложения разделена таким образом, что можно изменять одну его часть, так чтобы изменения не повлияли на другую его часть.
По такой схеме, логика кода WP-API разделена на независимые компоненты (классы):
- Класс получения запроса.
- Классы контроллеров (обработка запросы и создание ответа).
- Класс ответа на запрос (получает подготовленный контроллером ответ и формирует его в стандартный JSON вид, устанавливает заголовки ответа и код ответа).
Класс запроса и ответа - это Классы инфраструктуры WP API, с ними как правило работать не нужно. Мы, разработчики, почти всегда будем работать с Классом контроллера.
Задача Класса контроллера объединить отдельные части обработки запроса API в единый механизм. В них должны создаваться маршруты, они получают запросы обрабатывают их и генерируют ответы. Так же там описывается схема ресурса.
Концепция контроллера принята в рамках WP-API для того, чтобы иметь стандартный шаблон для Классов контроллера - классов представляющих ресурсы (конечные точки). Шаблоном класса контроллера является абстрактный класс WP_REST_Controller. Каждый класс контроллера должен иметь аналогичную схему методов, сделано так для того, чтобы все конечные точки имели одинаковые названия PHP методов.
Классы инфраструктуры и Классы контроллеров
Классы инфраструктуры дополняют классы контроллеров - они обрабатывают логику API, но не выполняют преобразований данных. Также и классы контроллеров (конечных точек) инкапсулируют логику необходимую для выполнения CRUD операций с ресурсами, но не связаны с логикой инфраструктуры. Это и есть упомянутая выше модель «Model-View-Controller».
К классам инфраструктуры относятся:
- WP_REST_Server — фундаментальный контроллер REST API, который обслуживает запрос. При любом запросе к API сначала вызывается WP_REST_Server и определяет, какой запрашивается маршрут, а затем передает коллбэк маршрута в объект WP_REST_Request. WP_REST_Server также выполняет проверку аутентификации и проверки валидации и доступа (validation и permissions).
- WP_REST_Request — этот объект содержит сведения о запросе, такие как заголовки запроса, параметры и метод, а также сам маршрут. Он также может проверять и очищать запрос (validation и sanitization).
- WP_REST_Response — отвечает за ответ на запрос. Устанавливает заголовки ответа, статус, тело ответа (JSON). Предоставляет вспомогательные методы add_link() (добавляет связанные с ответом ссылки) и query_navigation_headers() (данные навигации в заголовках).
К классам контроллеров относятся:
- WP_REST_Posts_Controller
- WP_REST_Users_Controller
- ...
- Все классы REST API смотрите здесь.
Пример регистрации маршрута через Класс контроллера
Подробное описание этого примера смотрите в разделе Создание маршрутов.
GitHubПринципы Классов контроллеров в WP API
Классы контроллеров решают две проблемы при разработке эндпоинтов:
- Отсутствие пространств имен — WordPress не использует пространства имён PHP (для поддержки PHP 5.2). Оборачивание группы PHP функций которые описывают конечную точку в класс, позволяет избежать конфликтов с названиями функций. Например, мы назвали функцию get_items() и другой разработчик сделал тоже самое, в результате сайт перестанет работать из-за фатальной ошибки PHP.
- Согласование структур — Один раз разобравшись со структурой класса контроллера, разработчики смогут быстро понимать структуру класса контроллера, которую писал другой человек.
Для классов контроллеров разработчиками создан специальный шаблон: абстрактный класс WP_REST_Controller. На его основе рекомендуется создавать свои контроллеры маршрутов. Так например, все классы конечных точек WP расширяют WP_REST_Controller, например:
class WP_REST_Posts_Controller extends WP_REST_Controller { // ... }
Методы класса-шаблона WP_REST_Controller:
Метод | Описание метода |
---|---|
register_routes() | вызывается при первом создания экземпляра класса и регистрирует маршруты. |
get_items() | получает коллекцию ресустов (постов, рубрик и т.д.). |
get_item() | получает отдельный ресурс (пост, рубрику и т.д.). Если ресурса не существует, будет возвращен HTTP статус 404. Если нет права просматривать ресурс, то статус будет 403. |
create_item() | создает новый ресурс. Если создание прошло успешно, то WP_REST_Response вернет HTTP статус 201 и ссылку на созданный ресурс. Если создание не удалось, то будет возвращен соответствующий код ошибки в HTTP заголовке. |
update_item() | обновляет существующий ресурс. |
delete_item() | удаляет существующий ресурс. Если удаление не удалось, то будет возвращен соответствующий код ошибки в HTTP заголовке. |
get_items_permissions_check() | перед вызовом коллбэк функции проверяет есть ли право у текущего запроса получать коллекцию ресурсов. |
get_item_permissions_check() | перед вызовом коллбэк функции проверяет есть ли право у текущего запроса получать отдельный ресурс. |
create_item_permissions_check() | перед вызовом коллбэк функции проверяет есть ли право у текущего запроса создавать ресурс. |
update_item_permissions_check() | перед вызовом коллбэк функции проверяет есть ли право у текущего запроса обновлять ресурс. |
delete_item_permissions_check() | перед вызовом коллбэк функции проверяет есть ли право у текущего запроса удалять ресурс. |
prepare_item_for_response() | изменяет данные ресурса, чтобы они подходили под схему ответа. |
prepare_response_for_collection() | prepare_item_for_response() возвращает объект WP_REST_Response. Это вспомогательная функция, которая собирает такие ответы в общую коллекцию ресурсов и возвращает эту коллекцию в качестве ответа. |
filter_response_by_context() | фильтрует данные ресурса в соответствии с указанным параметром context. |
get_item_schema() | получает объект схемы ресурса. |
Заметка про наследование классов
Не следует злоупотреблять наследованием классов. Например: если мы написали класс контроллера для эндпоинта записей (пример выше) и хотим также поддерживать произвольные типы записей, то не следует расширять свой класс My_REST_Posts_Controller следующим образом:
class My_CPT_REST_Controller extends My_REST_Posts_Controller { ... }
Вместо этого нужно либо создать отдельный класс контроллера, либо заставить My_REST_Posts_Controller обрабатывать все доступные типы записей. Дело в том, что родительский класс (тот который наследуется) может измениться, а наши подклассы зависят от него, в результате получаем головную боль. Поэтому, если нужна общая структура для классов, необходимо создать свой базовый класс контроллера в виде интерфейса или абстрактного класса, а затем использовать его как основу для подклассов. Такой подход абстрактного класса используется во многих конечных точках REST API WordPress. Например, классы WP_REST_Posts_Controller, WP_REST_Terms_Controller и т.д. расширяют абстрактный класс WP_REST_Controller.