В современных проектах на WordPress REST API становится неотъемлемой частью для взаимодействия с фронтендом и мобильными приложениями. Однако при большом объеме запросов или сложных вычислениях каждый вызов API может замедлять работу сайта. В этой статье мы подробно разберем, как создать глобальный кеш для REST API в WordPress, который позволяет значительно ускорить ответы и снизить нагрузку на сервер.
Почему важен кеш для REST API в WordPresses
REST API позволяет получать данные в формате JSON и используется для динамического обновления контента без перезагрузки страницы. Но каждый запрос к API — это выполнение PHP-кода и запросов к базе данных. При большом числе пользователей и сложных вычислениях это становится узким местом.
Кеширование ответов API позволяет хранить результаты запросов в быстром хранилище (например, в памяти или на диске) и возвращать их без повторных вычислений. Это снижает нагрузку на сервер и ускоряет выдачу данных.
В WordPress для кеширования можно использовать встроенный объектный кеш (transient API), внешние системы кеширования (Redis, Memcached) или собственные реализации.
Основные подходы к кешированию REST API в WordPress
1. Использование transient API для кеша ответов
Transient API — это простое решение для временного кеширования данных с заданным временем жизни. Пример использования:
function wordpresses_get_cached_api_response( $request ) {
$cache_key = 'wordpresses_api_cache_' . md5( json_encode( $request->get_params() ) );
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return rest_ensure_response( $cached );
}
// Выполняем длительные операции
$data = wordpresses_generate_api_data( $request );
set_transient( $cache_key, $data, 5 * MINUTE_IN_SECONDS );
return rest_ensure_response( $data );
}Здесь мы формируем уникальный ключ кеша по параметрам запроса, проверяем наличие кеша, если есть — возвращаем его, иначе генерируем данные и сохраняем.
2. Использование внешних кеш-систем (Redis, Memcached)
Для сайтов с высокой нагрузкой лучше использовать внешние кеш-системы, которые обеспечивают быстрый доступ к данным в памяти. Для этого в WordPress достаточно настроить соответствующий объектный кеш и использовать его методы:
function wordpresses_get_redis_cached_response( $request ) {
global $wp_object_cache;
$cache_key = 'wordpresses_api_cache_' . md5( json_encode( $request->get_params() ) );
$cached = $wp_object_cache->get( $cache_key, 'wordpresses_api' );
if ( false !== $cached ) {
return rest_ensure_response( $cached );
}
$data = wordpresses_generate_api_data( $request );
$wp_object_cache->set( $cache_key, $data, 'wordpresses_api', 300 );
return rest_ensure_response( $data );
}<Это решение требует, чтобы на сервере был настроен Redis и соответствующий плагин или настройка кеша в WordPress.
Как реализовать глобальный кеш для REST API в WordPresses
Под глобальным кешем понимается кеш, который действует для всех пользователей и запросов с одинаковыми параметрами, а не индивидуальный для каждого посетителя. Это особенно эффективно для публичных данных, которые часто запрашиваются.
Основные шаги:
- Генерируем уникальный ключ кеша по URL и параметрам запроса.
- Проверяем наличие кеша.
- Если кеш есть и он не устарел — возвращаем кешированные данные.
- Если кеша нет — запускаем обработку запроса и сохраняем результат.
Пример полного обработчика REST API с кешем
add_action( 'rest_api_init', function () {
register_rest_route( 'wordpresses/v1', '/items', [
'methods' => 'GET',
'callback' => 'wordpresses_rest_items_callback',
'permission_callback' => '__return_true',
]);
});
function wordpresses_rest_items_callback( WP_REST_Request $request ) {
$cache_key = 'wordpresses_api_cache_' . md5( $request->get_route() . serialize( $request->get_params() ) );
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return rest_ensure_response( $cached );
}
// Имитация длительной выборки данных
$data = wordpresses_fetch_items_from_db();
set_transient( $cache_key, $data, 10 * MINUTE_IN_SECONDS );
return rest_ensure_response( $data );
}
function wordpresses_fetch_items_from_db() {
// Здесь может быть сложный запрос, например WP_Query с фильтрами
$query = new WP_Query([
'post_type' => 'post',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
]);
$items = [];
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
$items[] = [
'id' => get_the_ID(),
'title' => get_the_title(),
'date' => get_the_date(),
];
}
wp_reset_postdata();
}
return $items;
}В этом примере мы создаем собственный endpoint /wordpresses/v1/items, который возвращает последние 10 записей, кэшируя ответ на 10 минут.
Как обновлять кеш при изменении данных
Чтобы кеш не устаревал, нужно очищать соответствующие кеши при изменении контента. Для этого используем хуки WordPress:
function wordpresses_clear_api_cache_on_post_update( $post_id ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
global $wpdb;
$transient_name_like = 'wordpresses_api_cache_%';
$wpdb->query( $wpdb->prepare(
"DELETE FROM $wpdb->options WHERE option_name LIKE %s",
'_transient_' . $transient_name_like
) );
}
add_action( 'save_post', 'wordpresses_clear_api_cache_on_post_update' );Этот код удаляет все transient, начинающиеся с префикса wordpresses_api_cache_, при сохранении записи. Это гарантирует, что кеш обновится при следующем запросе.
Варианты более точечной очистки кеша
Если API зависит от параметров, можно сохранять ключи кеша в отдельной опции и удалять только нужные. Это усложняет код, но повышает эффективность.
Рекомендации по оптимизации кеша REST API в WordPresses
- Используйте уникальные ключи кеша, учитывая все параметры запроса.
- Выбирайте подходящий срок жизни кеша в зависимости от частоты обновления данных.
- При высокой нагрузке рекомендуем использовать Redis или Memcached вместо transient API.
- Обязательно очищайте кеш при изменении данных, чтобы пользователи получали актуальную информацию.
- Логируйте время обработки запросов для контроля эффективности кеширования.
Пример простой логики логирования
function wordpresses_log_api_response_time( $start_time, $cache_hit ) {
$duration = microtime( true ) - $start_time;
error_log( sprintf( 'REST API %s: %.4f сек', $cache_hit ? 'cache hit' : 'cache miss', $duration ) );
}Вызывайте эту функцию в начале и конце обработки запроса, чтобы видеть, насколько кеш ускоряет ответ.