Замена admin-ajax на REST API эндпоинты
Иногда может быть удобно заменить ajax запросы в админке на запросы с использованием REST API. Это может сделать ваш код более лаконичным, а запросы более безопасными.
Давайте рассмотрим следующий пример. Допустим код плагина добавляет страницу админки. На этой странице есть кнопка и область для результата AJAX запроса. При клике на кнопку выполняется ajax-запрос который получает последние записи, затем заголовки этих записей отображаются.
Использование WP AJAX
В этом примере нет реализации nonce для безопасности, но это обязательно нужно добавить в реальном плагине.
Для начала нужно подключить наш JS скрипт:
add_action( 'admin_enqueue_scripts', 'wp_learn_rest_enqueue_script' );
function wp_learn_rest_enqueue_script() {
wp_enqueue_script(
'myscript',
plugin_dir_url( __FILE__ ) . 'myscript.js',
[ 'jquery' ],
false,
true
);
}
Теперь напишем скрипт для обработки события нажатия на кнопку и выполнения Ajax-запроса.
/**
* Обработка Ajax-запроса
*/
jQuery( document ).ready(
function ( $ ) {
const loadPostsButton = $( '#ajax-button' );
if ( loadPostsButton ) {
loadPostsButton.on(
'click',
function ( event ) {
$.post(
ajaxurl,
{
'action': 'learn_fetch_posts',
},
function ( posts ) {
const textarea = $( '#wp-learn-posts' );
posts.forEach( function ( post ) {
textarea.append( post.post_title + '\n' )
} );
},
)
},
);
}
},
);
Заметка: Тут мы используем js переменную ajaxurl, которая автоматически определена в адмни-панели.
Теперь нужно создать функцию для обработки ajax-запроса. Для этого вешаем коллбэк на хук wp_ajax_*
add_action( 'wp_ajax_learn_fetch_posts', 'my_ajax_fetch_posts' );
function my_ajax_fetch_posts() {
$posts = get_posts();
wp_send_json( $posts );
// Все обработчики ajax должны прекратить работу PHP по завершению своей работы
wp_die();
}
Использование WP REST API
Теперь рассмотрим как такая задача будет выглядеть, если использовать WP REST API.
Теперь не нужен обработчик ajax-запроса, поэтому можем удалить функцию my_ajax_fetch_posts и связанный хук.
WordPress поставляется с клиентом Backbone JavaScript для выполнения прямых запросов к WP REST API.
Чтобы убедиться, что ваш код может использовать клиент Backbone.js, вам просто нужно обновить зависимость вашего плагина с jquery на wp-api.
Это обеспечит загрузку JavaScript-кода вашего плагина только после загрузки JavaScript-клиента REST API, чтобы вы могли использовать его в вашем js скрипте.
В JavaScript-файле сначала вы можете удалить код, связанный с jQuery/Ajax.
Затем вам нужно будет зарегистрировать обработчик события клика для новой кнопки.
const loadPostsByRestButton = document.getElementById( 'wp-learn-rest-api-button' );
if ( loadPostsByRestButton ) {
loadPostsByRestButton.addEventListener( 'click', function () {
// сделать что-то
} );
}
Затем в функции обработчика событий вы можете использовать WP API client, получая его из глобального объекта wp, чтобы создать новую коллекцию записей:
const allPosts = new wp.api.collections.Posts();
На этом этапе "allPosts" — это просто пустая коллекция, поэтому вам нужно будет получить записи, вызвав метод "fetch" на коллекции.
allPosts.fetch();
Метод "fetch" возвращает промис, поэтому вы можете цепочкой использовать метод done для обработки ответа и реализовать функцию обратного вызова, которая примет ответ от запроса API. Вы можете указать аргумент posts в этой функции обратного вызова, чтобы принять ответ от запроса API
const posts = allPosts.fetch().done(
function ( posts ) {
// сделать что-то с записями
}
);
Теперь можно перебрать объект posts, используя метод "forEach".
const posts = allPosts.fetch().done(
function ( posts ) {
posts.forEach( function ( post ) {
// сделать что-то с записью
} );
}
);
Наконец, можно добавить заголовок записи в область результат ответа. Сначала вам нужно создать экземпляр текстовой области перед циклом forEach, а затем добавить заголовок записи к свойству value текстовой области внутри цикла forEach.
const posts = allPosts.fetch().done(
function ( posts ) {
const textarea = document.getElementById( 'wp-learn-posts' );
posts.forEach( function ( post ) {
textarea.value += post.title.rendered + '\n'
} );
}
);
Финальный код будет выглядеть примерно так:
const loadPostsByRestButton = document.getElementById( 'wp-learn-rest-api-button' );
if ( loadPostsByRestButton ) {
loadPostsByRestButton.addEventListener( 'click', function () {
const allPosts = new wp.api.collections.Posts();
allPosts.fetch().done(
function ( posts ) {
const textarea = document.getElementById( 'wp-learn-posts' );
posts.forEach( function ( post ) {
textarea.value += post.title.rendered + '\n'
} )
}
);
} );
}
Заключение
Большое преимущество использования WP REST API и JavaScript-клиента Backbone.js заключается в том, что вы можете использовать один и тот же клиент снова и снова. Например, если вы хотите получить пользователей, вы можете просто создать новую коллекцию пользователей и получить их. Чтобы сделать это через admin-ajax, вам потребуется либо новая функция обработчика admin_ajax, либо обновить существующую функцию, чтобы она принимала параметр для определения того, что получать.
Другим преимуществом является то, что API JavaScript-клиент обрабатывает проверку nonce за вас. С admin-ajax вам нужно указывать это самостоятельно и проверять в вашей функции обработчика. Таким образом, используя REST API и JavaScript-клиент, ваши запросы становятся более безопасными.