Статьи

WP REST API: внутренние компоненты и настройка

В предыдущей части серии мы узнали о создании, обновлении и удалении контента через API REST WP. Это позволяет нам создавать независимые от платформы приложения, которые бесперебойно работают с серверной частью на базе WordPress, предоставляя пользователю богатый опыт.

В текущей части серии мы рассмотрим внутреннюю часть WP REST API и то, как они работают вместе для обеспечения работы API. После этого мы научимся изменять ответы сервера для конечных точек по умолчанию, чтобы включить настраиваемые поля.

Чтобы быть конкретным, в текущей статье мы будем:

  • узнать о внутренних классах и методах WP REST API
  • изменить ответ сервера для конечных точек по умолчанию
  • узнайте, как сделать настраиваемые поля редактируемыми

Итак, начнем с рассмотрения внутренних частей WP REST API.

Классы в API REST WP можно разделить на следующие две категории:

  1. Классы инфраструктуры : это фундаментальные классы, отвечающие за объединение API. Они не выполняют никакого преобразования данных.
  2. Классы конечных точек : эти классы отвечают за выполнение операций CRUD над ресурсами, такими как сообщения, страницы, пользователи, комментарии и т. Д.

Давайте посмотрим на отдельные классы каждой из двух вышеуказанных категорий.

Три класса инфраструктуры, которые вместе используют REST API, следующие:

  1. WP_REST_Server
  2. WP_REST_Request
  3. WP_REST_Response

Это основной класс API REST WP, который реализует сервер REST путем регистрации маршрутов, обслуживания запросов и подготовки ответов. Он форматирует данные, передаваемые клиенту, и в случае ошибки готовит ошибку, включая код ошибки и текст сообщения. Он также проверяет подлинность.

Мы довольно много работали с конечной точкой индекса /wp-json для проверки всех возможностей и поддерживаемых маршрутов для сайта. Метод get_index() , который отвечает за получение индекса сайта, также находится в этом классе.

Для обслуживания запросов и подготовки ответов класс WP_REST_Server использует WP_REST_Request и WP_REST_Response соответственно.

Класс WP_REST_Request реализует объект запроса для WP REST API. Он содержит данные из запроса, такие как заголовки и тело запроса, и передается в функцию обратного вызова классом WP_REST_Server . Он также проверяет, являются ли параметры, переданные по запросу, действительными и выполняет очистку данных, когда это необходимо.

Класс WP_REST_Response , как следует из названия, реализует объект ответа. Он содержит необходимые данные, такие как код состояния ответа и тело ответа.

Давайте теперь посмотрим на классы конечных точек.

Классы конечных точек в API REST WP отвечают за выполнение операций CRUD. Эти классы включают WP_REST_Posts_Controller , WP_REST_Taxonomies_Controller , WP_REST_Users_Controller и т. Д. Все эти классы конечных точек расширяют один абстрактный класс WP_REST_Controller который обеспечивает согласованный шаблон для изменения данных.

Класс WP_REST_Controller включает такие методы, как get_item() , create_item() , update_item() , delete_item() и т. Д., Для выполнения операций CRUD. Эти методы должны быть переопределены подклассами путем реализации их собственной абстракции для извлечения, создания, обновления и изменения данных.

Вы можете найти больше об этих классах и их внутренних методах в официальной документации .

Узнав о внутренних классах API-интерфейса WP REST, давайте посмотрим, как мы можем изменить ответы сервера для конечных точек по умолчанию, чтобы включить настраиваемые поля.

В предыдущем разделе мы рассмотрели внутренние классы и методы, на которых построен API. Вместе эти классы и методы управляют API в целом и предоставляют разработчикам возможность расширить API для учета различных сценариев и вариантов использования.

WP REST API предоставляет данные предсказуемым образом. Это включает в себя различные ресурсы, такие как сообщения, мета публикации, страницы и пользователи, а также их стандартные свойства. Но эти данные не всегда могут соответствовать потребностям каждого сайта или пользователя WordPress. Поэтому API-интерфейс WP REST предоставляет способ изменения данных, которые сервер возвращает для каждого из маршрутов по умолчанию.

Метод register_rest_field() предоставляет способ добавления или обновления полей в ответе для объекта. Однако API никогда не поощряет изменение поля из ответа, поскольку это может привести к проблемам совместимости для клиентов, ожидающих стандартного ответа от сервера. Таким образом, если вам нужно изменить поле, вы должны продублировать поле с нужным значением.

Точно так же удаление поля по умолчанию крайне не рекомендуется по той причине, что клиент может ожидать его. Если вам нужно меньшее подмножество ответа, возвращаемого сервером, вы должны создать дополнительные контексты в дополнение к контекстам по умолчанию, таким как view или edit .

Однако мы можем безопасно добавить поле к ответу, возвращаемому сервером для одного или нескольких объектов. Эти поля могут содержать любое значение в диапазоне от мета post или user до любого другого произвольного значения.

В следующем разделе мы будем работать с методом register_rest_field() чтобы добавить настраиваемые поля в ответ, возвращаемый сервером для объекта post .

Как упоминалось ранее, метод register_rest_field() может использоваться для добавления или обновления полей в ответе, возвращаемом сервером. Этот метод принимает три аргумента:

  1. $object_type
  2. $attribute
  3. $args

Аргумент $object_type может быть либо строкой, либо массивом, содержащим имена всех объектов, для которых мы хотим добавить поле. Этими объектами могут быть post , term , comment , user и т. Д. Если нам нужно добавить настраиваемое поле для настраиваемого типа записи, то аргумент $object_type будет именем типа записи.

Аргумент $attribute — это имя настраиваемого поля. Это имя будет отображаться в ответе сервера как ключ вместе с его значением.

Массив $args — это ассоциативный массив, который может содержать следующие три ключа:

  1. $get_callback
  2. $update_callback
  3. $schema

Значения первых двух ключей — это имена методов, которые используются для получения или обновления значения настраиваемого поля. Последний ключ $schema определяет метод или переменную, которая используется для определения схемы для настраиваемого поля.

Все вышеперечисленные ключи являются необязательными, но если они не добавлены, возможность не будет добавлена. Например, если вы определяете ключ $get_callback но не ключ $update_callback , функция извлечения будет добавлена, но функция обновления не будет добавлена. Если вы пропустите ключ $get_callback , поле вообще не будет добавлено к ответу.

Метод register_rest_field() работает путем изменения переменной $wp_rest_additional_fields . Эта переменная массива содержит зарегистрированные поля по типам объектов, которые должны быть возвращены в ответе сервером. Всякий раз, когда поле регистрируется методом register_rest_field() , оно добавляется в переменную $wp_rest_additional_fields . Однако, изменение переменной $wp_rest_additional_fields вручную настоятельно не рекомендуется.

Ознакомившись с методом register_rest_field() , мы можем теперь изменить ответ для объекта post . Типичным примером использования здесь является добавление поля отображаемого имени автора, которое обычно требуется при перечислении сообщений на странице индекса. Поскольку стандартный ответ не включает это поле, мы можем использовать метод register_rest_field() чтобы включить его в ответ.

Мы начинаем с создания простого плагина. Поэтому создайте новую папку с именем rest-response-modifier в каталоге / wp-content / plugins . Создайте пустой файл index.php и вставьте следующее определение плагина:

1
2
3
4
5
6
7
<?php
/**
 * Plugin Name: REST Response Modifier
 * Description: A very simple plugin for development and testing purpose to modify the response of the REST API plugin.
 * Author: Bilal Shahid
 * Author URI: http://imbilal.com
 */

Метод register_rest_field() должен быть зарегистрирован в действии rest_api_init . Следовательно, мы создаем функцию с именем bs_add_custom_rest_fields() и привязываем ее к rest_api_init :

1
2
3
4
5
6
<?php
add_action( ‘rest_api_init’, ‘bs_add_custom_rest_fields’ );
 
function bs_add_custom_rest_fields() {
     
}

Обратите внимание, что открывающие теги PHP <?php здесь не требуются, но я включил их, чтобы синтаксис был выделен правильно.

Внутри функции bs_add_custom_rest_fields() мы можем использовать метод register_rest_field() чтобы включить поле для имени автора:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
function bs_add_custom_rest_fields() {
    // schema for the bs_author_name field
    $bs_author_name_schema = array(
        ‘description’ => ‘Name of the post author’,
        ‘type’ => ‘string’,
        ‘context’ => array( ‘view’ )
    );
     
    // registering the bs_author_name field
    register_rest_field(
        ‘post’,
        ‘bs_author_name’,
        array(
            ‘get_callback’ => ‘bs_get_author_name’,
            ‘update_callback’ => null,
            ‘schema’ => $bs_author_name_schema
        )
    );
}

Как упоминалось в предыдущем разделе, первый аргумент в методе register_rest_field() — это имя объекта, для которого мы модифицируем ответ. Поскольку нам нужно изменить ответ для объекта post , мы передаем то же самое, что и первый аргумент.

Вторым аргументом в приведенном выше коде является имя поля, которое появится в ответе. Всегда рекомендуется добавлять в ответ префикс имени настраиваемого поля, чтобы обеспечить максимальную прямую совместимость и чтобы в будущем оно не переопределялось другими плагинами. Следовательно, мы передаем bs_author_name во втором аргументе как $attribute пользовательского поля.

Третий и последний аргумент в приведенном выше коде является массивом для методов обратного вызова и схемы. Этот массив содержит имя методов обратного вызова для извлечения и обновления настраиваемого поля в $get_callback и $update_callback соответственно. Мы bs_get_author_name функцию bs_get_author_name в качестве метода обратного вызова. Мы определим эту функцию в ближайшее время.

Для ключа $update_callback мы передаем null поскольку это поле $update_callback только для чтения, и нам не нужно обновлять имя автора сообщения.

Для ключа $schema мы передаем массив с именем $bs_author_name_schema . Этот массив содержит различные свойства для поля, такие как тип данных, контекст и описание.

Единственное, что нам нужно определить сейчас — это bs_get_author_name() которая будет действовать как метод $get_callback для нашего настраиваемого поля. Ниже приведен код этой функции:

01
02
03
04
05
06
07
08
09
10
/**
 * Callback for retrieving author name
 * @param array $object The current post object
 * @param string $field_name The name of the field
 * @param WP_REST_request $request The current request
 * @return string The name of the author
 */
function bs_get_author_name( $object, $field_name, $request ) {
    return get_the_author_meta( ‘display_name’, $object[‘author’] );
}

Метод $get_callback получает три аргумента для следующего:

  1. $object : текущий объект. В нашем случае это текущий пост.
  2. $field_name : имя добавляемого настраиваемого поля.
  3. $request : объект запроса.

Мы используем свойство $author аргумента $object которое содержит идентификатор автора сообщения. А с помощью функции get_the_author_meta() мы получаем и возвращаем отображаемое имя автора для текущего сообщения.

Теперь, когда поле зарегистрировано, мы можем отправить запрос GET по маршруту /wp/v2/posts чтобы проверить, работает ли оно правильно:

Вот ответ в Почтальоне:

отклик

Это вновь зарегистрированное настраиваемое поле также появится в ответе сервера вместе со схемой, когда мы отправим запрос OPTIONS на маршрут /wp/v2/posts :

схема

Следовательно, пользовательское поле для свойства имени автора было успешно зарегистрировано. Но это поле доступно только для чтения, поскольку мы не можем обновить его, отправив запрос POST . В следующем разделе мы зарегистрируем редактируемое поле для подсчета просмотров.

Теперь мы зарегистрируем настраиваемое поле для количества просмотров постов. Мы будем иметь дело только с фактической регистрацией поля с помощью WP REST API, оставляя за собой реализацию для увеличения числа счетчиков.

Ниже приведен код для bs_post_views настраиваемого поля bs_post_views вместе со схемой:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
// schema for bs_post_views field
$bs_post_views_schema = array(
    ‘description’ => ‘Post views count’,
    ‘type’ => ‘integer’,
    ‘context’ => array( ‘view’, ‘edit’ )
);
 
// registering the bs_post_views field
register_rest_field(
    ‘post’,
    ‘bs_post_views’,
    array(
        ‘get_callback’ => ‘bs_get_post_views’,
        ‘update_callback’ => ‘bs_update_post_views’,
        ‘schema’ => $bs_post_views_schema
    )
);

Код похож на тот, который мы написали в предыдущем разделе, за исключением того, что теперь он включает метод обратного вызова bs_update_post_views для ключа $update_callback . Эта функция отвечает за обновление значения поля.

Свойство $context в $bs_post_views_schema схемы $bs_post_views_schema включает в себя два значения для view и edit . Включение значения edit в аргумент $context гарантирует, что поле bs_post_views будет возвращено в ответе сервера после его обновления.

Методы обратного вызова для поиска и обновления:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Callback for retrieving post views count
* @param array $object The current post object
* @param string $field_name The name of the field
* @param WP_REST_request $request The current request
* @return integer Post views count
*/
function bs_get_post_views( $object, $field_name, $request ) {
    return (int) get_post_meta( $object[‘id’], $field_name, true );
}
 
/**
* Callback for updating post views count
* @param mixed $value Post views count
* @param object $object The object from the response
* @param string $field_name Name of the current field
* @return bool|int
*/
function bs_update_post_views( $value, $object, $field_name ) {
    if ( ! $value || ! is_numeric( $value ) ) {
        return;
    }
 
    return update_post_meta( $object->ID, $field_name, (int) $value );
}

Код довольно прост, поскольку он использует get_post_meta() и update_post_meta() для получения и обновления значений соответственно.

Метод bs_get_post_views() сначала получает мета-значение для мета-ключа bs_post_views и преобразует его в целое число, а затем возвращает.

Метод обратного вызова, переданный в $update_callback получает три аргумента для следующего:

  1. $value : новое значение для поля.
  2. $object : текущий объект из ответа.
  3. $field_name : имя обновляемого поля.

В bs_update_post_views() мы сначала проверяем, не является ли передаваемое значение не пустым и является числовым значением. Если нет, мы возвращаемся, ничего не делая.

Если значение является числовым, мы передаем его в update_post_meta() которая сохраняет его в базе данных после преобразования типа в допустимое целое число.

После успешной регистрации поля давайте проверим его, отправив запрос GET :

1
$ GET /wp/v2/posts

Ниже приведен пример ответа на вышеуказанный запрос:

ответ

Как мы видим на изображении выше, текущее значение поля bs_post_views равно 0 для данного сообщения. Это связано с тем, что метод get_post_meta() возвращает пустую строку, поскольку он не может найти мета-значение для мета-ключа bs_post_views а приведение типа пустой строки в целое число в PHP приводит к 0.

Мы можем обновить поле bs_post_views , отправив запрос POST конечной точке /wp/v2/posts/<id> . Тело JSON для запроса выглядит следующим образом:

1
2
3
{
    «bs_post_views»: 4050
}

Если запрос выполнен успешно, сервер возвращает код состояния 200 — ОК вместе с обновленным объектом post, который также включает поле bs_post_views :

ответ

Настраиваемое поле bs_post_views теперь обновлено.

Обратите внимание, что мы отправили тело JSON вдоль запроса на обновление поля. Тело JSON включает имя поля — bs_post_views — с целочисленным значением 4050 . Если мы попытаемся отправить нечисловое значение, скажем “abc1234” , поле не будет обновлено, поскольку у нас есть проверка условия для числового значения в bs_update_post_views() обратного вызова bs_update_post_views() .

Ниже приведен полный исходный код для плагина:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php
/**
 * Plugin Name: REST Response Modifier
 * Description: A very simple plugin for development and testing purpose to modify the response of the REST API plugin.
 * Author: Bilal Shahid
 * Author URI: http://imbilal.com
 */
 
add_action( ‘rest_api_init’, ‘bs_add_custom_rest_fields’ );
 
/**
 * Function for registering custom fields
 */
function bs_add_custom_rest_fields() {
    // schema for the bs_author_name field
    $bs_author_name_schema = array(
        ‘description’ => ‘Name of the post author’,
        ‘type’ => ‘string’,
        ‘context’ => array( ‘view’ )
    );
     
    // registering the bs_author_name field
    register_rest_field(
        ‘post’,
        ‘bs_author_name’,
        array(
            ‘get_callback’ => ‘bs_get_author_name’,
            ‘update_callback’ => null,
            ‘schema’ => $bs_author_name_schema
        )
    );
     
    // schema for bs_post_views field
    $bs_post_views_schema = array(
        ‘description’ => ‘Post views count’,
        ‘type’ => ‘integer’,
        ‘context’ => array( ‘view’, ‘edit’ )
    );
     
    // registering the bs_post_views field
    register_rest_field(
        ‘post’,
        ‘bs_post_views’,
        array(
            ‘get_callback’ => ‘bs_get_post_views’,
            ‘update_callback’ => ‘bs_update_post_views’,
            ‘schema’ => $bs_post_views_schema
        )
    );
}
 
/**
 * Callback for retrieving author name
 * @param array $object The current post object
 * @param string $field_name The name of the field
 * @param WP_REST_request $request The current request
 * @return string The name of the author
 */
function bs_get_author_name( $object, $field_name, $request ) {
    return get_the_author_meta( ‘display_name’, $object[‘author’] );
}
 
/**
 * Callback for retrieving post views count
 * @param array $object The current post object
 * @param string $field_name The name of the field
 * @param WP_REST_request $request The current request
 * @return integer Post views count
 */
function bs_get_post_views( $object, $field_name, $request ) {
    return (int) get_post_meta( $object[‘id’], $field_name, true );
}
/**
 * Callback for updating post views count
 * @param mixed $value Post views count
 * @param object $object The object from the response
 * @param string $field_name Name of the current field
 * @return bool|int
 */
function bs_update_post_views( $value, $object, $field_name ) {
    if ( ! $value || ! is_numeric( $value ) ) {
        return;
    }
 
    return update_post_meta( $object->ID, $field_name, (int) $value );
}

Это все для изменения ответов сервера для конечных точек API по умолчанию. Мы едва коснулись поверхности для изменения REST API, поскольку она обеспечивает гораздо большую гибкость, чем просто изменение ответов сервера. Это включает добавление поддержки для пользовательского типа контента через пользовательские контроллеры и пространства имен, а также регистрацию пользовательских маршрутов для предоставления и изменения данных. Мы постараемся осветить эти сложные темы в будущих статьях.

На этом мы завершаем наше знакомство с WP REST API. В этой серии мы рассмотрели довольно простые понятия, такие как методы аутентификации, а также извлечение, создание и обновление данных. В этой последней части серии мы кратко рассмотрели внутренние классы API-интерфейса WP REST, а затем научились изменять ответы сервера для конечных точек по умолчанию.

Целью этой серии никогда не было охватить каждый аспект API REST WP — фактически его никогда нельзя достичь за одну серию. Но скорее цель этой серии состояла в том, чтобы заставить вас работать с этим новым фантастическим дополнением и побудить вас поиграть и поэкспериментировать самостоятельно. Я надеюсь, что вы нашли, что эта серия выполняет свою конечную цель.