Работа с WP REST API часто требует не только обработки входящих запросов, но и выполнения сложных или длительных задач. Например, импорт данных, генерация отчетов, отправка писем или синхронизация с внешними сервисами — все это может занимать время и нагрузить сервер, если делать сразу в момент запроса. В таких случаях полезно реализовать отложенное выполнение задач через REST API, чтобы быстро отдавать ответ клиенту и запускать тяжелую операцию в фоне.
Проблемы с длительными задачами в REST API WordPress
Типичный REST API эндпоинт в WordPress обрабатывается синхронно: запрос пришел — функция обработчика запустилась — вернула результат — клиент получил ответ. Если внутри функции идет длительная операция, например, запросы к внешним API, обработка больших файлов или сложные вычисления, то время ответа сильно растет. Клиент может получить таймаут, сервер может перегрузиться или пользователь столкнется с медленной работой.
Кроме того, в стандартном WordPress нет встроенного механизма для очередей задач, поэтому нужно либо использовать WP Cron, либо внешние сервисы, либо создавать собственные решения.
Реализация отложенного выполнения через WP Cron и REST API
Самый простой способ — при получении REST API запроса сразу создавать задачу в WP Cron, возвращать клиенту успешный ответ и уже в фоне запускать обработку. Рассмотрим пример, как это сделать.
Регистрация кастомного REST API эндпоинта
Создадим эндпоинт /wp-json/wpapi/v1/start-task, который будет создавать отложенную задачу.
add_action('rest_api_init', function () {
register_rest_route('wpapi/v1', '/start-task', [
'methods' => 'POST',
'callback' => 'wpapi_start_task',
'permission_callback' => function () {
return current_user_can('edit_posts');
}
]);
});
function wpapi_start_task(WP_REST_Request $request) {
$params = $request->get_params();
// Планируем задачу через WP Cron через 1 минуту
if (!wp_next_scheduled('wpapi_do_task', [$params])) {
wp_schedule_single_event(time() + 60, 'wpapi_do_task', [$params]);
}
return new WP_REST_Response(['status' => 'started'], 202);
}
Обработка отложенной задачи
Регистрируем хук, который выполняет задачу:
add_action('wpapi_do_task', function ($params) {
// Здесь тяжелая обработка, например, импорт данных
// wpapi_do_heavy_task($params);
// Для примера просто логируем
error_log('Запущена отложенная задача с параметрами: ' . print_r($params, true));
});
Использование плагина для очередей задач
WP Cron подходит не всегда, особенно если нагрузка высокая или важна надежность. Для таких задач можно использовать плагины-менеджеры очередей, например, Clearfy Pro с расширенными возможностями оптимизации и управления задачами или специализированные решения как WP Queue Manager.
Такие плагины позволяют создавать очередь задач с повторными попытками, управлять приоритетами и отслеживать статус выполнения. Они зачастую имеют удобный интерфейс и API для интеграции с WP REST API.
Прямое выполнение через AJAX и асинхронные запросы
Если задача запускается с фронтенда, можно разбить процесс на несколько небольших шагов и запускать их последовательно через AJAX-запросы или fetch. Каждый такой вызов будет небольшим и быстрым, а общая задача выполнится постепенно. Это снижает нагрузку на сервер и позволяет информировать пользователя о прогрессе.
Пример разделения задачи на части
Допустим, нужно обработать 1000 записей. Можно сделать REST API метод, который обрабатывает 50 записей за один вызов и возвращает прогресс. Фронтенд запускает его циклом или через таймер, пока задача не завершится.
Практические советы по безопасности и надежности
- Обязательно проверяйте права пользователя в REST API, чтобы исключить несанкционированный запуск задач.
- Используйте nonce и другие методы защиты от CSRF, особенно если задачи запускаются с фронтенда.
- Логируйте ошибки и успешные запуски, чтобы можно было отследить сбои и проблемы.
- Если задача критична, реализуйте повторные попытки и уведомления об ошибках.
- Оптимизируйте код тяжелых операций, чтобы минимизировать время выполнения и нагрузку.
Итоговый код для отложенного запуска задачи через WP REST API
add_action('rest_api_init', function () {
register_rest_route('wpapi/v1', '/start-task', [
'methods' => 'POST',
'callback' => 'wpapi_start_task',
'permission_callback' => function () {
return current_user_can('edit_posts');
}
]);
});
function wpapi_start_task(WP_REST_Request $request) {
$params = $request->get_params();
if (!wp_next_scheduled('wpapi_do_task', [$params])) {
wp_schedule_single_event(time() + 60, 'wpapi_do_task', [$params]);
}
return new WP_REST_Response(['status' => 'started'], 202);
}
add_action('wpapi_do_task', function ($params) {
// Выполнение тяжелой задачи
// Например, импорт данных, отправка писем и т.д.
error_log('Выполнена отложенная задача с параметрами: ' . print_r($params, true));
});
Используйте этот подход, чтобы не блокировать клиентов и обеспечивать стабильную работу сервера при длительных операциях, вызываемых через WP REST API.