REST API WordPress разработка: пошаговое создание пользовательских эндпоинтов

Почему стоит использовать собственный REST API в WordPress

Стандартный набор эндпоинтов WordPress покрывает базовые задачи (посты, страницы, пользователи), но в реальных проектах часто требуется бизнес‑логика, которой нет в ядре. Пользовательский REST API позволяет:

  • Интегрировать сайт с мобильными приложениями и внешними сервисами;
  • Сократить количество запросов, объединяя несколько действий в один эндпоинт;
  • Контролировать уровень доступа и формат ответа под нужды клиента.

Для разработки безопасных и быстрых API важно правильно регистрировать маршруты и учитывать рекомендации по ускорению сайта и кэшированию.

Регистрация кастомных маршрутов: register_rest_route

Все пользовательские эндпоинты регистрируются в хук rest_api_init. Функция register_rest_route принимает три аргумента: пространство имён, путь и массив параметров.

add_action( 'rest_api_init', function () {
    register_rest_route( 'myplugin/v1', '/orders', [
        'methods'  => WP_REST_Server::READABLE, // GET
        'callback'  => 'myplugin_get_orders',
        'permission_callback' => 'myplugin_orders_permissions',
    ] );
} );

В примере создаётся маршрут myplugin/v1/orders, доступный только методом GET.

Обработка запросов: методы GET, POST, PUT, DELETE

Для каждого HTTP‑метода указывается константа из WP_REST_Server:

  • READABLE – GET
  • CREATABLE – POST
  • EDITABLE – PUT/PATCH
  • DELETABLE – DELETE

Пример POST‑эндпоинта

register_rest_route( 'myplugin/v1', '/order', [
    'methods'  => WP_REST_Server::CREATABLE,
    'callback' => 'myplugin_create_order',
    'permission_callback' => 'myplugin_create_order_permissions',
] );

function myplugin_create_order( WP_REST_Request $request ) {
    $data = $request->get_json_params();
    // Валидация и сохранение заказа
    $order_id = wp_insert_post([
        'post_type'   => 'shop_order',
        'post_status' => 'wc-pending',
        'meta_input'  => [ 'items' => $data['items'] ],
    ]);
    return new WP_REST_Response( ['order_id' => $order_id], 201 );
}

Объект WP_REST_Request предоставляет удобные методы get_param(), get_json_params() и т.д.

Авторизация и безопасность эндпоинтов

WordPress поддерживает несколько схем аутентификации: куки‑авторизация, OAuth 2.0, JWT, Basic Auth. Для большинства внутренних приложений достаточно проверки прав пользователя.

Пример проверки прав

function myplugin_orders_permissions( WP_REST_Request $request ) {
    // Только администраторы могут видеть все заказы
    return current_user_can( 'manage_woocommerce' );
}

Если требуется публичный доступ, следует реализовать nonce‑проверку или токены, иначе ваш API станет уязвим к спаму и DDoS‑атакам.

Формат ответа и обработка ошибок

Стандартный ответ – объект WP_REST_Response. Он позволяет задать статус, заголовки и тело ответа.

return new WP_REST_Response( [
    'success' => true,
    'data'    => $result,
], 200 );

Для ошибок используйте WP_Error:

if ( empty( $order_id ) ) {
    return new WP_Error( 'order_creation_failed', 'Не удалось создать заказ', [ 'status' => 500 ] );
}

Клиент получит JSON вида {"code":"order_creation_failed","message":"Не удалось создать заказ","data":{"status":500}}.

Практический пример: API для корзины WooCommerce

Рассмотрим простой эндпоинт, который возвращает содержимое текущей корзины и позволяет добавить товар. Такой функционал часто используют в одностраничных приложениях, где важна скорость. Для оптимизации запросов рекомендуется включить кэширование ответов через плагин WP Rocket или аналог.

Регистрация маршрутов

add_action( 'rest_api_init', function () {
    // Получить корзину
    register_rest_route( 'woo/v1', '/cart', [
        'methods' => WP_REST_Server::READABLE,
        'callback' => 'woo_get_cart',
        'permission_callback' => '__return_true',
    ] );
    // Добавить товар в корзину
    register_rest_route( 'woo/v1', '/cart/add', [
        'methods' => WP_REST_Server::CREATABLE,
        'callback' => 'woo_add_to_cart',
        'permission_callback' => '__return_true',
    ] );
} );

Обработчики

function woo_get_cart( WP_REST_Request $request ) {
    $cart = WC()->cart->get_cart();
    $items = [];
    foreach ( $cart as $item ) {
        $product = $item['data'];
        $items[] = [
            'id'    => $product->get_id(),
            'name'  => $product->get_name(),
            'price' => $product->get_price(),
            'qty'   => $item['quantity'],
        ];
    }
    return new WP_REST_Response( $items, 200 );
}

function woo_add_to_cart( WP_REST_Request $request ) {
    $params = $request->get_json_params();
    $product_id = intval( $params['product_id'] );
    $quantity   = intval( $params['quantity'] ?? 1 );
    $added = WC()->cart->add_to_cart( $product_id, $quantity );
    if ( ! $added ) {
        return new WP_Error( 'add_to_cart_failed', 'Не удалось добавить товар', [ 'status' => 400 ] );
    }
    return new WP_REST_Response( [ 'message' => 'Товар добавлен' ], 201 );
}

После добавления эндпоинтов вы получаете два URL:

  • https://example.com/wp-json/woo/v1/cart – GET, возвращает JSON‑массив товаров;
  • https://example.com/wp-json/woo/v1/cart/add – POST, тело запроса {"product_id":123,"quantity":2}.

Для ускорения работы магазина не забудьте изучить проверенные методы оптимизации WooCommerce.

Тестирование и отладка

Для быстрой проверки используйте curl или плагин Postman. В WordPress включите WP_DEBUG и просматривайте логи запросов через error_log(). При работе с внешними клиентами рекомендуется добавить заголовок Access-Control-Allow-Origin: * или ограничить домены.

Заключение

Создание собственного REST API в WordPress – мощный способ расширить функциональность сайта без изменения ядра. Правильная регистрация маршрутов, проверка прав и грамотный формат ответов обеспечат безопасность и производительность. Применяйте полученные знания в проектах, комбинируя их с кэш‑плагинами и оптимизацией WooCommerce, и ваш сайт будет готов к работе с любыми клиентскими приложениями.

❓ Часто задаваемые вопросы

Как добавить кастомный параметр в запрос REST API?

Используйте метод register_rest_route и укажите параметр в массиве args. В обработчике запросов получайте значение через $request->get_param('my_param').

Можно ли ограничить доступ к эндпоинту только по токену?

Да, в permission_callback проверьте заголовок Authorization, сравнив его с вашими JWT‑или API‑ключами, и верните true только при совпадении.

Что делать, если API возвращает статус 500?

Включите WP_DEBUG_LOG, проверьте логи wp-content/debug.log и убедитесь, что в обработчике не происходит необработанных исключений или ошибок базы данных.

Как кешировать ответы пользовательского API?

Добавьте заголовок Cache-Control в объект WP_REST_Response или используйте плагины типа WP Rocket, которые умеют кешировать REST‑запросы.