WP REST API — параметры для фильтрации запросов.

Это продолжение статьи “WP REST API(дефолтное) — взаимодействие с WP сайтом,” в которой я повествовал о работе с дефолтным апи вордпрес. Однако, той статье я ничего не рассказываю о пагинации или получении связанных обьектов в одном запросе, ну и тд… в общем, эта статья ксть дополнением к той(по этому прочтите ее).

Параметры пагинации

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

https://guten.xyz/wp-json/wp/v2/posts

Cейчас мы получим JSON-строку, содержащую массив обьектов всех постов(или 100, если их больше). Но если нам не нужны они все? Здесь все просто – нужно указать параметры пагинации(аналогичные им же в обьекте WP_Query). Этот запрос ограничит нашу выборку 5-ю постами ч 2-ой страницы

https://guten.xyz/wp-json/wp/v2/posts?per_page=5&page=2

Как видно, были добавлены 2 GET-параметра – per_page и page. На деле их 4(5)(если порядок сортировки результатов относить к пагинации).

Третий параметр(offset) позволяет настроить сдвиг, т.е. количество постов, которое нужно пропустить(еще не придумал ситуации где он нужен, может, для разбития самой страницы…). И четвертый(order и orderby, да, их два – обманул) – определяют поле для сортировки(второй) и порядок сортировки(первый).

В итоге, запрос, который будет выводить последние 3 поста с второй страницы, содержащей по 5 постов на страницу и в порядке убывание id, выглядит так

https://guten.xyz/wp-json/wp/v2/posts?per_page=3&page=2&offset=2&sortby=id&sort=desc

Сортируемые поля у каждого типа обьекта разные… и, к полной картине, заголовки ответа(в полях X-WP-Total и X-WP-TotalPages) содержится

Заголовки HTTP-ответа
Заголовки HTTP-ответа

информация о количестве записей и количестве страниц, при данном разбиении. Немного уточнений по offset – он отбрасывает не n первых постов на каждой странице, а n первых постов согласно параметров сортировки.

Ссылание и встраивание

Каждый полученный обьект содержит поле _links, представляющее собой массив ссылок на апи-пути связанных обьектов. Также, эти массивы имеют поле embeddable, несущее информацию о том, можно ли этот связанный обьект встроить в текущий.

Для примера, воспользуемся обращением к постам; ответ содержит только id изображения миниатюры, но не саму ссылку на него(которую можно вставить в тег img, к примеру). В поле _links есть следующий обьект

Ссылка на связанный обьект
Ссылка на связанный обьект

В этом участке информации меня интересует не так ссылка на обьект, как то, что поле embeddable имеет значение true, т.е. обьект может быть встроен в текущий. Чтобы его встроить, нужно к текущему запросу дописатьь еще один гет-параметр _embed с значением нужного обьекта; в моем случаи

https://guten.xyz/wp-json/wp/v2/posts?per_page=5&page=2&_embed=wp:featuredmedia

при этом в каждом родительском объекте появится поле _embedded, содержащий требуемый обьект(равный тоому, который будет ответом по ссылке).

Встроенный объект
Встроенный объект

Фильтр полей

В WP REST API есть get-атрибут _fields, позволяющий заказать поля, которые нужно получить. Это нужно, как вы понимаете, для оптимизации запросов к серверу, что б он не “лег” в пиковые моменты… но не только! Также, этим параметром можно заказывать различные зарегистрированные метаполя. Рассмотрим пример получения id, title и метаполя counter; для начала зарегистрируем его в rest

<?php
// как мета данные
register_meta( 'post', 'counter', array(
	'type'              => 'string',
	'description'       => "Счетчик просмотров",
	'single'            => true,
	'sanitize_callback' => null,
	'auth_callback'     => null,
	'show_in_rest'      => true,
) );
// как обычное поле
add_action( 'rest_api_init', function(){

	register_rest_field( 'post', 'counter', array(
		'get_callback' => function( $post ){
			return get_post_meta( $post->ID, 'counter', true );
		},
		'update_callback' => null,
		'schema' => [
			'description' => "Счетчик просмотров", 
			'type' => 'string'
		],
	) );

} );

теперь можно получить коллекцию обьектов

https://guten.xyz/wp-json/wp/v2/posts?_fields=id,title,meta.counter
# или
https://guten.xyz/wp-json/wp/v2/posts?_fields=id,title,counter

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