WordPress с версии 4.7 имеет встроенный REST API, который позволяет взаимодействовать с сайтом через HTTP-запросы. Однако зачастую стандартного API недостаточно, и требуется создать собственные конечные точки (endpoints) для решения специфических задач. В этой статье подробно разберём, как создать собственный REST API в WordPress, используя примеры кода и рекомендации по безопасности.
Что такое REST API в WordPress и зачем создавать собственный
REST API — это архитектурный стиль взаимодействия между клиентом и сервером по протоколу HTTP. В WordPress REST API позволяет получать, создавать, обновлять и удалять данные сайта через стандартные HTTP-запросы (GET, POST, PUT, DELETE).
Стандартные методы API покрывают основные типы данных: посты, страницы, таксономии, пользователи. Но что делать, если нужно создать собственный функционал, например, получать данные из кастомных таблиц, реализовать сложную бизнес-логику или интегрироваться с внешними сервисами? В таком случае создаётся собственный endpoint с уникальным маршрутом и обработчиком.
Преимущества собственного REST API:
- Гибкость в реализации любых бизнес-задач.
- Возможность создания мобильных и SPA-приложений на базе WordPress.
- Безопасный доступ к данным с кастомной аутентификацией и проверками.
Регистрация собственного REST API в WordPress (hook rest_api_init)
Для регистрации собственного endpoint используется хук rest_api_init. Внутри колбэка вызывается функция register_rest_route(), которая задаёт маршрут, методы и обработчик запроса.
Пример простого кода для регистрации GET-запроса:
add_action('rest_api_init', 'wpinc_register_custom_endpoint');
function wpinc_register_custom_endpoint() {
register_rest_route('wpinc/v1', '/hello/', [
'methods' => 'GET',
'callback' => 'wpinc_hello_callback'
]);
}
function wpinc_hello_callback(WP_REST_Request $request) {
return [
'message' => 'Привет от WPINC REST API!'
];
}В этом примере создаётся endpoint по адресу /wp-json/wpinc/v1/hello/, который возвращает JSON с сообщением.
Разбор параметров register_rest_route
Первый параметр — префикс пространства имён (namespace), обычно в формате название_сайта/v1. Второй — путь (route), определяющий конкретный endpoint. Третий — массив с настройками:
methods— HTTP-методы, которые поддерживает endpoint (GET, POST, PUT, DELETE и др.).callback— функция-обработчик запроса.permission_callback— функция проверки прав доступа, обязательна для безопасности (подробнее ниже).
Обработка запросов и получение параметров
В функцию обратного вызова передаётся объект WP_REST_Request, который позволяет получить параметры из URL, тела запроса, заголовков и др.
Пример получения параметра name из URL:
function wpinc_hello_callback(WP_REST_Request $request) {
$name = $request->get_param('name');
if (!$name) {
$name = 'Гость';
}
return [
'message' => "Привет, $name!"
];
}Для передачи параметров можно использовать query string ?name=Иван или POST-запрос с JSON-телом.
Регистрация параметров и валидация
Чтобы задать параметры API и контролировать их типы и обязательность, можно использовать аргумент args в register_rest_route. Это позволяет автоматически валидировать входящие данные.
register_rest_route('wpinc/v1', '/hello/', [
'methods' => 'GET',
'callback' => 'wpinc_hello_callback',
'args' => [
'name' => [
'required' => false,
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field'
]
]
]);Реализация безопасности: permission_callback
Безопасность — ключевой момент при создании API. Функция permission_callback должна проверять, имеет ли пользователь право выполнять запрос.
Пример разрешения доступа только авторизованным пользователям:
register_rest_route('wpinc/v1', '/secret-data/', [
'methods' => 'GET',
'callback' => 'wpinc_get_secret_data',
'permission_callback' => function() {
return is_user_logged_in();
}
]);Если нужен доступ по правам роли или capability, используйте функции current_user_can().
Пример: создание CRUD для кастомного типа записей через REST API
Допустим, у вас есть кастомный тип записей book. Создадим endpoints для получения списка книг, создания новой, обновления и удаления.
Регистрация маршрутов:
add_action('rest_api_init', 'wpinc_register_books_routes');
function wpinc_register_books_routes() {
register_rest_route('wpinc/v1', '/books/', [
'methods' => 'GET',
'callback' => 'wpinc_get_books',
'permission_callback' => '__return_true'
]);
register_rest_route('wpinc/v1', '/books/', [
'methods' => 'POST',
'callback' => 'wpinc_create_book',
'permission_callback' => function() {
return current_user_can('edit_posts');
}
]);
register_rest_route('wpinc/v1', '/books/(?P<id>\d+)', [
'methods' => 'PUT',
'callback' => 'wpinc_update_book',
'permission_callback' => function() {
return current_user_can('edit_posts');
}
]);
register_rest_route('wpinc/v1', '/books/(?P<id>\d+)', [
'methods' => 'DELETE',
'callback' => 'wpinc_delete_book',
'permission_callback' => function() {
return current_user_can('delete_posts');
}
]);
}
function wpinc_get_books() {
$books = get_posts([
'post_type' => 'book',
'numberposts' => 10
]);
$data = [];
foreach ($books as $book) {
$data[] = [
'id' => $book->ID,
'title' => $book->post_title,
'content' => $book->post_content
];
}
return $data;
}
function wpinc_create_book(WP_REST_Request $request) {
$params = $request->get_json_params();
$post_id = wp_insert_post([
'post_type' => 'book',
'post_title' => sanitize_text_field($params['title']),
'post_content' => sanitize_textarea_field($params['content']),
'post_status' => 'publish'
]);
if (is_wp_error($post_id) || !$post_id) {
return new WP_Error('cant-create', 'Не удалось создать книгу', ['status' => 500]);
}
return ['id' => $post_id];
}
function wpinc_update_book(WP_REST_Request $request) {
$id = (int)$request->get_param('id');
$params = $request->get_json_params();
$post = get_post($id);
if (!$post || $post->post_type !== 'book') {
return new WP_Error('not_found', 'Книга не найдена', ['status' => 404]);
}
$updated = wp_update_post([
'ID' => $id,
'post_title' => sanitize_text_field($params['title']),
'post_content' => sanitize_textarea_field($params['content'])
], true);
if (is_wp_error($updated)) {
return new WP_Error('cant-update', 'Ошибка обновления книги', ['status' => 500]);
}
return ['updated' => true];
}
function wpinc_delete_book(WP_REST_Request $request) {
$id = (int)$request->get_param('id');
$post = get_post($id);
if (!$post || $post->post_type !== 'book') {
return new WP_Error('not_found', 'Книга не найдена', ['status' => 404]);
}
$deleted = wp_delete_post($id, true);
if (!$deleted) {
return new WP_Error('cant-delete', 'Ошибка удаления книги', ['status' => 500]);
}
return ['deleted' => true];
}Такой API позволит внешним приложениям управлять кастомным типом записей book по REST.
Тестирование и отладка собственного REST API
Для проверки API можно использовать инструменты Postman, Insomnia или curl.
Пример запроса с curl для получения списка книг:
curl -X GET https://your-site.ru/wp-json/wpinc/v1/books/Для POST-запроса с авторизацией можно использовать cookie или OAuth. Удобно тестировать с помощью плагина Clearfy Pro, который помогает оптимизировать безопасность и управлять правами.
Рекомендации и лучшие практики
- Всегда указывайте
permission_callbackдля контроля доступа. - Используйте валидацию и санитизацию данных.
- Пишите понятные и однозначные маршруты и версии API.
- Документируйте свои endpoints для удобства использования.
- Для сложных проектов рассмотрите использование плагинов типа WPGPT для расширения возможностей и автоматизации.
Создание собственного REST API — мощный инструмент для разработчиков, который открывает новые горизонты по интеграции и расширению WordPress. Следуйте изложенным рекомендациям и примерам для качественной и безопасной реализации.