WP REST API — мощный инструмент для взаимодействия с данными WordPress. Однако стандартные эндпоинты часто не позволяют удобно и гибко строить сложные запросы с фильтрацией по нескольким параметрам. В этой статье мы разберём, как расширить функционал WP REST API, добавив кастомные фильтры и параметры для сложных запросов, которые часто требуются в реальных проектах.
Почему стандартные фильтры WP REST API ограничены
По умолчанию в WP REST API доступны базовые параметры для запросов, такие как filter, search, orderby и другие. Однако они не всегда позволяют реализовать логику, необходимую для конкретных бизнес-задач. Например, фильтрация по нескольким пользовательским полям (custom fields), сложные условия «И»/«ИЛИ», или фильтрация с динамическими параметрами.
К тому же, стандартный параметр filter в новых версиях WordPress ограничен, и его использование не рекомендуется из соображений безопасности и производительности. Поэтому для расширенных фильтров нам придётся добавить свои параметры и обработчики.
Добавление кастомного параметра фильтрации в WP REST API
Для примера создадим расширение для стандартного эндпоинта постов /wp/v2/posts, которое позволит фильтровать записи по произвольному метаполю wp_temp_custom_field.
Добавим регистрацию параметра и обработку запроса с этим параметром. В functions.php вашей темы или в плагине добавьте следующий код:
add_action('rest_api_init', function() {
register_rest_route('wp/v2', '/posts', array(
'methods' => 'GET',
'callback' => 'wptemp_rest_filter_posts',
'args' => array(
'custom_field' => array(
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
),
'permission_callback' => '__return_true',
));
});
function wptemp_rest_filter_posts(WP_REST_Request $request) {
$custom_field_value = $request->get_param('custom_field');
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
);
if ($custom_field_value) {
$args['meta_query'] = array(
array(
'key' => 'wp_temp_custom_field',
'value' => $custom_field_value,
),
);
}
$query = new WP_Query($args);
$posts = array();
foreach ($query->posts as $post) {
$posts[] = array(
'id' => $post->ID,
'title' => get_the_title($post),
);
}
return rest_ensure_response($posts);
}Теперь запрос GET /wp-json/wp/v2/posts?custom_field=значение вернёт посты, у которых метаполе wp_temp_custom_field равно переданному значению.
Расширение фильтрации: несколько параметров и сложные условия
Часто требуется фильтровать записи сразу по нескольким метаполям или условиям. Для этого расширим пример, добавив поддержку нескольких параметров и логики «И»/«ИЛИ».
Допустим, нам нужно фильтровать по двум метаполям: wp_temp_custom_field1 и wp_temp_custom_field2. При этом пользователь может указать, использовать ли условие «И» (AND) или «ИЛИ» (OR).
Добавим в код поддержку этих параметров:
add_action('rest_api_init', function() {
register_rest_route('wp/v2', '/posts', array(
'methods' => 'GET',
'callback' => 'wptemp_rest_filter_posts_advanced',
'args' => array(
'custom_field1' => array(
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
'custom_field2' => array(
'required' => false,
'sanitize_callback' => 'sanitize_text_field',
),
'relation' => array(
'required' => false,
'validate_callback' => function($param) {
return in_array(strtoupper($param), array('AND', 'OR'));
},
'default' => 'AND',
),
),
'permission_callback' => '__return_true',
));
});
function wptemp_rest_filter_posts_advanced(WP_REST_Request $request) {
$custom_field1 = $request->get_param('custom_field1');
$custom_field2 = $request->get_param('custom_field2');
$relation = strtoupper($request->get_param('relation')) ?: 'AND';
$meta_query = array('relation' => $relation);
if ($custom_field1) {
$meta_query[] = array(
'key' => 'wp_temp_custom_field1',
'value' => $custom_field1,
);
}
if ($custom_field2) {
$meta_query[] = array(
'key' => 'wp_temp_custom_field2',
'value' => $custom_field2,
);
}
$args = array(
'post_type' => 'post',
'posts_per_page' => 10,
);
if (count($meta_query) > 1) { // relation + at least one condition
$args['meta_query'] = $meta_query;
}
$query = new WP_Query($args);
$posts = array();
foreach ($query->posts as $post) {
$posts[] = array(
'id' => $post->ID,
'title' => get_the_title($post),
);
}
return rest_ensure_response($posts);
}Теперь можно делать запросы с параметрами:
?custom_field1=foo&custom_field2=bar&relation=AND— посты, где оба метаполя равны соответствующим значениям.?custom_field1=foo&custom_field2=bar&relation=OR— посты, где хотя бы одно из метаполей равно значению.
Безопасность и производительность кастомных фильтров
При расширении WP REST API важно учитывать безопасность и производительность:
- Валидация и санитизация: всегда проверяйте и очищайте входящие параметры, чтобы избежать SQL-инъекций и других атак.
- Ограничение объёма выборки: используйте
posts_per_pageи пагинацию, чтобы не перегружать сервер. - Кэширование: при сложных запросах имеет смысл использовать Transients API или внешние кэши (Redis, Memcached) для ускорения ответов.
- Правила доступа: если данные чувствительные, реализуйте проверку прав доступа в
permission_callback.
Пример использования плагина Clearfy Pro для расширения WP REST API
Плагин Clearfy Pro предлагает дополнительные инструменты для оптимизации и настройки WordPress, включая расширенное управление API. Если вы используете Clearfy Pro, можно активировать функции, которые ограничивают доступ к REST API для неавторизованных пользователей и настраивают фильтрацию запросов без написания кода.
Подробнее о Clearfy Pro и его возможностях вы можете узнать на официальной странице плагина.
Выводы и рекомендации
Расширение WP REST API с помощью кастомных фильтров — мощный способ сделать ваш сайт и приложение более гибкими и удобными в работе с данными. Главное — правильно спроектировать параметры, обеспечить безопасность и следить за производительностью.
Используйте приведённые примеры кода как основу для своих проектов и адаптируйте под конкретные задачи. А для упрощения управления API рассмотрите популярные плагины, например, Clearfy Pro.