Обнаружение REST API

Обнаружение — это любые действия, которые направлены на выяснения того, как работает REST API. Например:

  • По какому URL находится корневой каталог API.
  • Какую схему имеет ресурс.
  • Какие параметры имеет конкретный эндпоинт.
  • Какие плагины/темы расширили (используют) REST API.

Как правило все виды обнаружения сводятся к чтению схемы маршрута или схемы всего WP API, но чтобы можно было прочитать такую схему нужно выяснить (обнаружить) какой у REST API корневой URL. В PHP получить корневой URL можно с помощью функции rest_url().

Рекомендуемый путь обнаружить URL на REST API это отправить HEAD запрос на любую страницу сайта и проверить есть ли в ответе параметр Link:. Rest API автоматически добавляет параметр Link в заголовки ответа для всех страниц во фронтэнде.

Link: <http://example.com/wp-json/>; rel="https://api.w.org/"

Указанная в параметре ссылка ведет на корневой маршрут REST API (/). Его можно использовать для дальнейшего обнаружения маршрутов.

Для сайтов с отключенными ЧПУ /wp-json/ автоматически не обрабатывается в WordPress. И в таком случае ссылка на REST API будет выглядеть так:

Link: <http://example.com/?rest_route=/>; rel="https://api.w.org/"

Для клиентов которые не умеют читать HEADER заголовки ответа (которые парсят HTML или запускаются в браузере), URL на REST API можно получить в HTML метатеге link в <head> части документа. Такой метатег также добавляется на всех страницах во вонтэнде.

<link rel='https://api.w.org/' href='http://example.com/wp-json/' />

В Javascript эту ссылку можно получить через DOM:

// jQuery вариант
var api_root = jQuery( 'link[rel="https://api.w.org/"]' ).attr( 'href' );

// Нативный JS
var links = document.getElementsByTagName( 'link' );
var link = Array.prototype.filter.call( links, function ( item ) {
	return item.rel === 'https://api.w.org/';
} );
var api_root = link[0].href;

Такое обнаружение также справедливо для обнаружения Atom/RSS фидов. Таким образом этот код можно адаптировать пот эту потребность.

Обнаружение через RSD

Для клиентов с поддержкой XML-RPC обнаружения, возможно удобнее будет получить ссылку на REST API через XML. Тут нужно сделать два шага:

Первый шаг: найти конечную точку (URL) RSD, она расположена также в <link> элементе в <head> части на любой странице фронтэнда:

<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://example.com/xmlrpc.php?rsd" />

Второй шаг: получить XML код по обнаруженной ссылке и распарсить его. Выглядит он примерно так:

<?xml version="1.0" encoding="utf-8"?>
<rsd version="1.0" xmlns="http://archipelago.phrasewise.com/rsd">
  <service>
	<engineName>WordPress</engineName>
	<engineLink>https://wordpress.org/</engineLink>
	<homePageLink>http://example.com/</homePageLink>
	<apis>
	  <api name="WordPress" blogID="1" preferred="true" apiLink="http://example.com/xmlrpc.php" />
	  <!-- ... -->
	  <api name="WP-API" blogID="1" preferred="false" apiLink="http://example.com/wp-json/" />
	</apis>
  </service>
</rsd>

Элемент со ссылкой на REST API всегда будет иметь атрибут name="WP-API".

RDS обнаружение это НЕ рекомендуемый способ, потому что он наиболее сложный, тут нужно сначала найти ссылку на RDS затем распарсить код по этой ссылки и только потом получить URL самого REST API.

По возможности рекомендуется избегать такого RDS обнаружения!

Обнаружение способов Авторизации

Обнаружение также позволяет узнать какие методы аутентификации имеются в REST API. Ответ главного маршрута REST API /wp-json/ содержит объект, который полностью описывает API. В этом объекте под ключом authentication находятся данные о возможных способах авторизации в REST API:

{
	"name": "Example WordPress Site",
	"description": "YOLO",
	"routes": { ... },
	"authentication": {
		"oauth1": {
			"request": "http://example.com/oauth/request",
			"authorize": "http://example.com/oauth/authorize",
			"access": "http://example.com/oauth/access",
			"version": "0.1"
		}
	}
}

Подробнее про аутентификацию в REST API читайте в соответствующем разделе.

Обнаружение имеющихся Расширений

После того, как REST API обнаружен, нужно узнать что API поддерживает. Узнать какие расширения есть в API можно из ответа на корневой маршрут REST API /wp-json/. Там под ключом namespaces находятся все имеющиеся расширения API:

Для WP версий от 4.4 до 4.6, доступны только базовое расширение oEmbed (полное API описанное в этом руководстве еще недоступно).

{
	"name": "Тестовый сайт",
	"namespaces": [
		"oembed/1.0/"
	]
}

С версии WP 4.7 доступно уже все API, так можно видеть новое расширение wp/v2:

{
	"name": "Тестовый сайт",
	"namespaces": [
		"wp/v2",
		"oembed/1.0/"
	]
}

Прежде чем пытаться использовать любую из конечных точек, нужно убедиться, что она поддерживается в API, для этого нужно проверить наличие нужного пространства имен, например wp/v2.

WordPress 4.4 включает инфраструктуру API для всех сайтов, но не включает основные конечные точки под wp/v2. Конечные точки ядра работают с версии WordPress 4.7.

Этот же механизм можно использовать для определения поддержки REST расширений у плагинов. Например, представим что плагин регистрирует следующий маршрут:

register_rest_route( 'testplugin/v1', '/testroute', array( /* ... */ ) );

Тогда в данных API появится новое расширение testplugin/v1:

{
	"name": "Тестовый сайт",
	"namespaces": [
		"wp/v2",
		"oembed/1.0/",
		"testplugin/v1"
	]
}