В современном веб-разработке часто возникает задача интеграции WordPress с внешними системами через REST API. Особенно популярным становится автоматический импорт данных из сторонних API с учетом пагинации и надежной обработкой ошибок. В этой статье подробно рассмотрим, как реализовать такую систему на примере WordPress, чтобы импортировать данные последовательно, не теряя информацию и не перегружая сервер.
Понимание задачи: зачем нужен автоматический импорт с пагинацией и обработкой ошибок
Многие API возвращают данные порциями (страницами), чтобы снизить нагрузку и ограничить объем ответа. При импорте большого количества записей нужно корректно обрабатывать эти страницы, запрашивая следующую, пока данные не закончатся. Также API могут возвращать ошибки (таймауты, неправильные параметры, превышение лимитов), которые нужно грамотно обрабатывать, чтобы импорт не прерывался и не создавал дубликаты.
Без правильной пагинации и обработки ошибок импорт может оказаться неполным, или процесс придется запускать вручную по нескольку раз. Поэтому автоматизация с учетом этих моментов — залог стабильной работы сайта.
Выбор инструментов WordPress для работы с REST API
Для работы с внешними API в WordPress удобно использовать встроенную функцию wp_remote_get(), которая позволяет делать HTTP-запросы и получать ответы с проверкой ошибок.
Для запуска автоматического импорта можно применить WP Cron или реализовать вызов через AJAX, если нужно обновлять данные по запросу из админки. В нашем примере используем WP Cron для регулярного запуска.
Для хранения состояния импорта (например, номер текущей страницы) применим опции WordPress через функции get_option() и update_option().
Пример кода: автоматический импорт с пагинацией и обработкой ошибок
Ниже приведен пример функции, которая делает запрос к API, обрабатывает ошибки и пагинацию. Функция вызывается через WP Cron и сохраняет данные в кастомный тип записи.
function wpcoding_import_from_api() {
$page = (int) get_option('wpcoding_import_page', 1);
$per_page = 50; // количество записей на странице
$api_url = 'https://example.com/api/items?page=' . $page . '&per_page=' . $per_page;
$response = wp_remote_get($api_url, [
'timeout' => 15,
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer YOUR_API_TOKEN'
]
]);
if (is_wp_error($response)) {
error_log('WPCoding API import error: ' . $response->get_error_message());
return; // ошибка запроса
}
$code = wp_remote_retrieve_response_code($response);
if ($code !== 200) {
error_log('WPCoding API import HTTP code: ' . $code);
return; // неверный код ответа
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if (empty($data) || !isset($data['items'])) {
error_log('WPCoding API import: пустой или некорректный ответ');
return; // нет данных
}
foreach ($data['items'] as $item) {
// Проверяем, есть ли запись с таким внешним ID
$existing = new WP_Query([
'post_type' => 'imported_item',
'meta_key' => 'wpcoding_external_id',
'meta_value' => $item['id'],
'posts_per_page' => 1
]);
if ($existing->have_posts()) {
continue; // уже импортировано
}
// Создаем запись
$post_id = wp_insert_post([
'post_title' => sanitize_text_field($item['title']),
'post_content' => wp_kses_post($item['description']),
'post_status' => 'publish',
'post_type' => 'imported_item'
]);
if (!is_wp_error($post_id)) {
update_post_meta($post_id, 'wpcoding_external_id', sanitize_text_field($item['id']));
}
}
// Проверяем, есть ли следующая страница
if (!empty($data['pagination']) && $data['pagination']['current_page'] < $data['pagination']['total_pages']) {
update_option('wpcoding_import_page', $page + 1);
} else {
update_option('wpcoding_import_page', 1); // сброс после завершения
}
}
// Регистрируем WP Cron событие
if (!wp_next_scheduled('wpcoding_import_cron_hook')) {
wp_schedule_event(time(), 'hourly', 'wpcoding_import_cron_hook');
}
add_action('wpcoding_import_cron_hook', 'wpcoding_import_from_api');
Разбор кода: что происходит внутри функции
1. С помощью get_option получаем текущую страницу импорта, чтобы не загружать все данные сразу.
2. Формируем URL с параметрами пагинации.
3. Выполняем HTTP GET запрос через wp_remote_get с таймаутом и заголовками.
4. Проверяем ошибки запроса и HTTP статус.
5. Декодируем JSON и проверяем наличие данных.
6. Для каждого элемента проверяем, не был ли он уже импортирован (по уникальному ID), чтобы избежать дубликатов.
7. Создаем новые записи с данными из API.
8. Обновляем номер страницы для следующего запуска или сбрасываем, если импорт завершен.
Создание кастомного типа записи для хранения импортированных данных
Для хранения импортированных записей лучше создать отдельный тип записей, чтобы не смешивать их с обычными постами. Добавьте следующий код в functions.php или в плагин:
function wpcoding_register_imported_item_cpt() {
register_post_type('imported_item', [
'labels' => [
'name' => 'Импортированные элементы',
'singular_name' => 'Импортированный элемент'
],
'public' => false,
'show_ui' => true,
'supports' => ['title', 'editor'],
'has_archive' => false,
'show_in_menu' => true
]);
}
add_action('init', 'wpcoding_register_imported_item_cpt');
Советы по улучшению и отладке импорта
- Используйте логирование ошибок в отдельный файл через
error_logили плагины, чтобы отслеживать проблемы. - Добавьте проверку лимитов API и реализуйте задержки (sleep), если сервис ограничивает частоту запросов.
- При больших объемах данных рассмотрите возможность загрузки через AJAX с прогрессом, чтобы не нагружать сервер WP Cron.
- Для сложных сценариев можно использовать WP Queue для последовательной обработки.
- Если нужно автоматически запускать импорт по событию, например, при публикации нового поста, добавьте соответствующие хуки.
Дополнительные плагины для автоматизации импорта в WordPress
Если не хотите писать код с нуля, обратите внимание на плагины, которые могут упростить задачу:
- WP Automatic — плагин для автоматического импорта контента из разных источников, включая REST API.
- Clearfy Pro — помогает оптимизировать и ускорить работу сайта, полезен для масштабных импортов.
Используйте приведенный пример кода как основу и адаптируйте под конкретное API и задачи вашего проекта. Такой подход обеспечит надежный и удобный автоматический импорт с учетом всех нюансов.