Замена 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-клиент, ваши запросы становятся более безопасными.