
Протокол REST API JSON в WordPress
1 марта 2019
Почему веб-разработчикам надо знать REST API? Ну как минимум чтобы делать правильные AJAX запросы. Без которых сегодня обходится редко какой сайт.
REST API для WordPress – это технология, которая применяется для множества современных задач:
- асинхронные запросы на сайте AJAX (это более адекватное решение чем использование популярного admin ajax)
- разработка SinglePageApplication (SPA) или виджетов на реактивном JavaScript аля React / Vue.js
- разработка мобильных приложений для iOS & Android, которым нужно получать данные с сайтом и обеспечивать взаимодействие
- интеграция систем – например листинг данных о товарах в Интернет-магазин на базе WordPress & WooCommerce
Проект вначале был загружен на GitHub для разработчиков в 2013 разработчиками Ryan McCue и Rachel Baker. Независимый плагин REST API был встроен в ядро WordPress в декабре 2015, после того, как получил огромную поддержку и привлёк желающих работать над улучшением его возможностей.
Делаем AJAX-запросы правильно
Большинство программистов в WordPress превратно понимают суть и работу AJAX. Все из-за залипания в словах. Есть у WordPress механизм admin-ajax, который хорошо документирован и 99% программистов уверены что AJAX надо делать через него.
“Эксперты” пишут статьи о том как это применять и почти ни у кого не возникает сомнений в адекватности такого решения.
А засада и ошибка заключается в том что admin-ajax был придуман для работы в админке. Там срабатывает тег is_admin. Тянется куча лишних файлов, кода и функционала. Для большинства маленьких сайтов ничего страшного, но если у вас более менее сложный сайт, на который приходит много функционала и трафика, то таким образом можно получить тормоза. А тормоза часто могут прибить сайт или испортить впечатление Клиентов о работе с вами.
Команда WooCommerce об этом знали, и еще до внедрения REST API – использовали правильный механизм работы с AJAX с фронта. См как работает класс WC_AJAX.
С приходом REST API у всех появилась возможность делать AJAX в WordPress правильно. Но стереотипы, шаблоны и привычки не дают этого. Многие до сих пор фигачат AJAX через admin ajax )
Простой пример
Простейший пример, который позволит отдать через REST API & AJAX какие то данные о сайте 🙂
Представим задачу сделать плагин “my-rest-api-example”, в котором будет 2 файла, которые в свою очередь обеспечат новый эндпоинт в REST API и JS + AJAX для получения и вывода данных.
my-rest-api-example.php
<?php
/*
 * Plugin Name: my-rest-api-example
 * Description: Simple example for REST API JSON WordPress
 * Version: 1.0
 */
class My_REST_API_Example{
  static public function init(){
    add_action( 'wp_enqueue_scripts', [__CLASS__, 'assets']);
    add_action( 'rest_api_init', function () {
      register_rest_route( 'my/v1', '/main-email', array(
        'methods' => 'GET',
        'callback' => [__CLASS__, 'rest_get_main_email'],
            ));
        });
  }
  /**
   * Frontend assets - scripts and styles
   */
  public static function assets(){
    wp_enqueue_script( 'wp-api' );
    wp_enqueue_script(
        $id = 'my-rest-api-example',
        $url = plugins_url( 'js-my-rest-api-example.js', __FILE__ ),
        $dep = array(
          'wp-api',
          'jquery',
        ),
        $ver = filemtime( plugin_dir_path( __FILE__ ) . 'js-my-rest-api-example.js' )
    );
  }
  /**
  * Готовим и отправляем данные через REST API
  */
  static public function rest_get_main_email(){
        $main_email = get_option('admin_email');
        if(empty($main_email )){
            wp_send_json_error();
        } else {
            wp_send_json_success($main_email);
        }
    }
}
My_REST_API_Example::init();js-my-rest-api-example.js
window.addEventListener('DOMContentLoaded', function() {
  var endpoint = 'my/v1/main-email/';
  var request_url = wpApiSettings.root + endpoint;
  jQuery.ajax({
    url: request_url,
    type: 'GET',
    success: function(result) {
      if (result.success === false) {
        console.log('error');
        return;
      }
      if(result.data){
        console.log(result.data);
      }
    },
 
  });
});
wpApiSettings для JavaScript
wpApiSettings – крайне важный объект для работы с REST API в WordPress. Там есть 2 переменные:
- wpApiSettings.root – тут содержится ссылка до корня REST API
- wpApiSettings.nonce – это nonce строка для авторизации пользователей
Чтобы проверить как это работает, надо написать в консоли браузера console.log(wpApiSettings);
Если у вас не подключена эта переменная, то получите ошибку: Uncaught ReferenceError: wpApiSettings is not defined
Чтобы эта переменная появилась, нужно на стороне php добавить загрузку JS клиента: wp_enqueue_script( 'wp-api' ) через хук wp_enqueue_scripts
Если клиент есть, то получите свой root и nonce. Которые можно подставлять в AJAX запросы у других скриптов.
Указываем путь до AJAX запроса без хардкода
Вы можете написать путь для AJAX запроса как то так: https://wpcraft.ru/wp-json/wc/v3/products – но при смене домена все это сломается. Птм лучше использовать wpApiSettings.root – которая всегда содержит актуальный путь до корня API и вам остается только подставлять окончание запроса (endpoint).
X-WP-Nonce и работа с пользователями
Если для работы вашего кода не нужно знать user_id, то вам не надо знать что такое X-WP-Nonce. Функция get_current_user_id() просто ничего не вернет.
Но если это требуется, то нужно использовать строку nonce, которая лежит там же в переменной wpApiSettings.nonce. Ее нужно подставить в заголовок запроса.
Пример
$.ajax( {
    url: wpApiSettings.root + 'wp/v2/posts/1',
    method: 'POST',
    beforeSend: function ( xhr ) {
        xhr.setRequestHeader( 'X-WP-Nonce', wpApiSettings.nonce );
    },
    data:{
        'title' : 'Hello Moon'
    }
} ).done( function ( response ) {
    console.log( response );
} );Сушим и ускоряем REST API
Если у вас большой нагруженный сайт с кучей функционала, то ваш REST API также может начать тормозить. Все потому что многие плагины нагружают хуки init и plugins_loaded, который находятся по ходу загрузки REST API. Сам WordPress не знает какие из этих плагинов нужны для REST API, а какие нет. Потому не может их отключить как ему вздумается. Но вы то знаете? Вы можете узнать какие из ваших плагинов тормозят, какие нужны в REST API, а какие нет. И те что не нужны – можно легко отключить из нагрузки REST API. Тем самым сильно ускорить запросы, TTFB и отдачу контента в 2-3-10 раз.
…




