WordPress REST: розробка кастомних API ендпоінтів

Розробка кастомних REST API ендпоінтів WordPress — наша спеціалізація вже 5+ років. Мобільний додаток SPA-фронтенду вимагає від WordPress агрегованих даних з фільтрацією за таксономіями та метаполями. Стандартний `/wp/v2/posts` не вміє видавати суму замовлень клієнта за період або список проєктів із

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
WordPress REST: розробка кастомних API ендпоінтів
Середній
~2-3 дні

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1418
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1286
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    983
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1243
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    983
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    998

Розробка кастомних REST API ендпоінтів WordPress — наша спеціалізація вже 5+ років. Мобільний додаток SPA-фронтенду вимагає від WordPress агрегованих даних з фільтрацією за таксономіями та метаполями. Стандартний /wp/v2/posts не вміє видавати суму замовлень клієнта за період або список проєктів із комбінованим сортуванням. Типова ситуація: без кешування при 5000 запитів на годину сервер падає. Розробники часто ліплять прямі SQL-запити, отримуючи N+1 проблем і вразливості. Наш досвід показав: правильно спроєктований кастомний ендпоінт вирішує ці задачі за 2–5 днів, знижуючи навантаження на базу в 3–5 разів. У цій статті розберемо типові сценарії, стек та архітектуру.

Щоб уникнути таких проблем, ми використовуємо єдиний інтерфейс для всіх даних: кастомний REST API ендпоінт агрегує записи, метаполя та таксономії за один запит. Це скорочує кількість HTTP-викликів у 5–10 разів і спрощує підтримку фронтенду. Наприклад, для одного з проєктів (каталог із 20 000 товарів) ми реалізували ендпоінт /my-plugin/v1/products з фільтрацією за категоріями, ціною та характеристиками — час відповіді скоротився з 4 до 1 секунди.

Обмеження стандартного REST API WordPress

Стандартні маршрути /wp/v2/posts та /wp/v2/pages хороші для читання записів, але не для:

  • Агрегованих даних — сума замовлень клієнта за останній місяць.
  • Складних фільтрів — комбінація метаполів і таксономій із сортуванням.
  • Кастомних операцій — створення замовлення з перевіркою стоку та відправкою email.

Без кастомного ендпоінту клієнту доводиться робити кілька запитів або використовувати небезпечні SQL-запити. Кастомний ендпоінт з кешуванням дозволяє скоротити час відповіді з 4 до 1 секунди.

Реєстрація кастомного REST API ендпоінту

Реєстрація ендпоінту з GET та POST методами. Детальніше в REST API Handbook.

add_action('rest_api_init', function () { register_rest_route('my-plugin/v1', '/projects', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_plugin_get_projects', 'permission_callback' => '__return_true', 'args' => [ 'category' => [ 'type' => 'string', 'sanitize_callback' => 'sanitize_title', ], 'tech' => [ 'type' => 'array', 'items' => ['type' => 'string'], 'sanitize_callback' => function ($value) { return array_map('sanitize_title', (array) $value); }, ], 'per_page' => [ 'type' => 'integer', 'default' => 12, 'minimum' => 1, 'maximum' => 100, 'sanitize_callback' => 'absint', ], 'page' => [ 'type' => 'integer', 'default' => 1, 'minimum' => 1, 'sanitize_callback' => 'absint', ], ], ], [ 'methods' => WP_REST_Server::CREATABLE, 'callback' => 'my_plugin_create_project', 'permission_callback' => function () { return current_user_can('edit_posts'); }, ], ]); register_rest_route('my-plugin/v1', '/projects/(?P<id>\d+)', [ 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_plugin_get_project', 'permission_callback' => '__return_true', 'args' => [ 'id' => [ 'validate_callback' => function ($param) { return is_numeric($param) && $param > 0; }, ], ], ]); }); 

Обробник GET-запиту з фільтрацією за таксономіями:

function my_plugin_get_projects(WP_REST_Request $request): WP_REST_Response|WP_Error { $per_page = $request->get_param('per_page'); $page = $request->get_param('page'); $category = $request->get_param('category'); $techs = $request->get_param('tech'); $query_args = [ 'post_type' => 'project', 'post_status' => 'publish', 'posts_per_page' => $per_page, 'paged' => $page, 'no_found_rows' => false, ]; $tax_queries = []; if ($category) { $tax_queries[] = [ 'taxonomy' => 'project_category', 'field' => 'slug', 'terms' => $category, ]; } if (!empty($techs)) { $tax_queries[] = [ 'taxonomy' => 'tech_stack', 'field' => 'slug', 'terms' => $techs, 'operator' => 'IN', ]; } if (!empty($tax_queries)) { $query_args['tax_query'] = array_merge(['relation' => 'AND'], $tax_queries); } $query = new WP_Query($query_args); $projects = []; foreach ($query->posts as $post) { $projects[] = my_plugin_format_project($post); } $response = new WP_REST_Response($projects, 200); $response->header('X-WP-Total', $query->found_posts); $response->header('X-WP-TotalPages', $query->max_num_pages); return $response; } function my_plugin_format_project(WP_Post $post): array { $thumbnail_id = get_post_thumbnail_id($post->ID); $thumbnail_url = $thumbnail_id ? wp_get_attachment_image_url($thumbnail_id, 'large') : null; return [ 'id' => $post->ID, 'slug' => $post->post_name, 'title' => wp_strip_all_tags($post->post_title), 'excerpt' => wp_strip_all_tags(get_the_excerpt($post)), 'url' => get_permalink($post->ID), 'thumbnail' => $thumbnail_url, 'client' => get_post_meta($post->ID, 'project_client', true), 'year' => (int) get_post_meta($post->ID, 'project_year', true), 'categories' => wp_get_post_terms($post->ID, 'project_category', ['fields' => 'slugs']), 'tech_stack' => wp_get_post_terms($post->ID, 'tech_stack', ['fields' => 'slugs']), 'modified' => get_post_modified_time('c', true, $post), ]; } 

Обробник POST з валідацією:

function my_plugin_create_project(WP_REST_Request $request): WP_REST_Response|WP_Error { $body = $request->get_json_params(); if (empty($body['title'])) { return new WP_Error('missing_title', 'Заголовок обов\'язковий', ['status' => 422]); } $post_id = wp_insert_post([ 'post_type' => 'project', 'post_title' => sanitize_text_field($body['title']), 'post_content' => wp_kses_post($body['content'] ?? ''), 'post_status' => 'draft', 'post_author' => get_current_user_id(), ], true); if (is_wp_error($post_id)) { return new WP_Error('insert_failed', $post_id->get_error_message(), ['status' => 500]); } if (!empty($body['client'])) { update_post_meta($post_id, 'project_client', sanitize_text_field($body['client'])); } return new WP_REST_Response( ['id' => $post_id, 'url' => get_permalink($post_id)], 201 ); } 

Який метод аутентифікації обрати?

Для GET-ендпоінтів достатньо публічного доступу. Для створення/зміни даних потрібна перевірка прав. Порівняємо методи:

Метод Сценарій Складність
Cookie Запити з адмінки Нульова (вбудований)
Application Passwords Зовнішні серверні клієнти Низька (офіційний плагін)
JWT SPA, мобільні додатки Середня (плагін або самописний код)

Приклад перехоплення Bearer-токена:

add_filter('rest_authentication_errors', function ($result) { if (!empty($result)) return $result; $auth_header = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; if (!str_starts_with($auth_header, 'Bearer ')) { return $result; } $token = substr($auth_header, 7); $user_id = my_plugin_validate_jwt($token); if (is_wp_error($user_id)) { return $user_id; } wp_set_current_user($user_id); return true; }); 

Кешування відповідей REST API

Для важких запитів використовуємо Transients API. Це знижує навантаження на БД у 3–5 разів. Приклад:

function my_plugin_get_projects(WP_REST_Request $request): WP_REST_Response { $cache_key = 'projects_' . md5(serialize($request->get_params())); $cached = get_transient($cache_key); if ($cached !== false) { $response = new WP_REST_Response($cached['data'], 200); $response->header('X-WP-Total', $cached['total']); $response->header('X-Cache', 'HIT'); return $response; } // ... основна логіка ... set_transient($cache_key, ['data' => $projects, 'total' => $total], 5 * MINUTE_IN_SECONDS); return $response; } add_action('save_post_project', function (int $post_id): void { global $wpdb; $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_projects_%'"); }); 

Що входить у розробку ендпоінтів

Етап Результат
Аналітика Визначення ендпоінтів, типів даних, методів аутентифікації
Проєктування Схема маршрутів, структура відповідей, валідація параметрів
Реалізація Написання коду, реєстрація роутів, обробники, кешування
Тестування Модульні тести (PHPUnit), ручне тестування через curl
Деплой Розгортання на бойовому сервері, налаштування моніторингу
Документація OpenAPI-схема або інструкція для розробників

Ми гарантуємо дотримання термінів і надаємо пост-релізну підтримку протягом 30 днів. Зв'яжіться з нами для оцінки вашого проєкту — ми проконсультуємо з архітектури та обсягу робіт. Замовте розробку кастомних ендпоінтів і скоротите час інтеграції вдвічі.

Порядок розробки кастомного REST API

  1. Аудит — визначаємо список ендпоінтів, методів (GET/POST/PUT/DELETE) та структури відповідей.
  2. Проєктування схеми маршрутів — версіонування (/my-plugin/v1/), аргументи, валідація параметрів.
  3. Реалізація обробників — написання callback-функцій, форматування даних, обробка помилок.
  4. Налаштування аутентифікації — Cookie (для адмінки), Application Passwords або JWT (для SPA/мобільних).
  5. Кешування — Transients API або Redis, інвалідація при зміні даних.
  6. Тестування через curl та PHPUnit, документація у OpenAPI-форматі.

Вартість розробки визначається після аналізу вашого проєкту. Це краще, ніж прямі SQL-запити з N+1 проблемами та вразливостями до SQL-ін'єкцій.

Як налагодити кастомний REST API WordPress?

Використовуйте curl -X GET https://site.com/wp-json/my-plugin/v1/projects -v для базової перевірки. Увімкніть WP_DEBUG та WP_DEBUG_LOG у wp-config.php — помилки PHP потраплять у debug.log. Плагін Query Monitor покаже всі SQL-запити, виконані під час виклику ендпоінту, і допоможе виявити N+1 проблеми. Перевірте заголовки відповіді: X-WP-Total має містити кількість записів, Content-Type: application/json. При помилці 401 переконайтеся, що permission_callback повертає true або коректно перевіряє права користувача.

Чому кастомні ендпоінти кращі за прямі SQL-запити?

Кастомний REST API ендпоінт забезпечує безпеку (фільтрація через WP API), кешування (Transients/Redis) та версіонування. За нашими даними, перехід на кастомні ендпоінти скорочує час на інтеграцію вдвічі та знижує кількість помилок на 60%. Приклади кастомних ендпоінтів: get_projects, create_order та ін. Більше 5 років ми розробляємо WordPress-рішення, запущено 30+ проєктів з кастомними REST API. Отримайте консультацію — оцінимо ваш проєкт і запропонуємо оптимальне рішення.