Как загружается REST в WordPress

REST запрос на 90% обрабатывается также как и запрос для фронтенда. Его также начинает обрабатывать файл index.php. Через правила перезаписи (ЧПУ) устанавливается параметр запроса rest_route=маршрут.

^wp-json/?$    => index.php?rest_route=/
^wp-json/(.*)? => index.php?rest_route=/$matches[1]

Процесс загрузки REST запроса выглядит так:

index.php
	// определяется константа WP_USE_THEMES

	wp-blog-header.php
		// ЯДРО (описано тут https://wp-kama.ru/handbook/wordpress/loading#wpcore-load)
		require_once dirname(__FILE__) . '/wp-load.php';

		// в процессе загрузки ядра создается хук `parse_request`
		// который срабатывает в функции `wp()`
		add_action( 'parse_request', 'rest_api_loaded' );

		// Установка основного запроса WordPress.
		// Делает запрос и определяет какая страница загружается.
		// В момент срабатывания хука `parse_request` управление передается
		// функции rest_api_loaded(), которая прерывает PHP через die.
		// См. https://wp-kama.ru/function/wp
		wp(); // См. WP::main()

Пояснения к работе wp() и хуку parse_request

Функция wp() вызывает метод WP::main(), он делает следующие действия по порядку:

  1. Вызывает WP::init().

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

    Позднее (если это REST запрос), на хуке аутентификации rest_authentication_errors авторизованный юзер будет обнулен при неправильном nonce коде. Смотрите:

  2. Вызывает WP::parse_request().

    Этот метод устанавливает параметры текущего запроса $wp->query_vars.

  3. Запуск REST — rest_api_loaded().

    В конце WP::parse_request() срабатывает хук parse_request на котором всегда висит функция rest_api_loaded():

    add_action( 'parse_request', 'rest_api_loaded' );

    rest_api_loaded() проверяет параметр запроса $GLOBALS['wp']->query_vars['rest_route']. Если это REST запрос, то запускается логика REST (логика обработки запросов для обычных страниц тут заканчивается).

    1. Устанавливается константа define( 'REST_REQUEST', true ).

    2. Запускается REST сервер rest_get_server().

      При запуске срабатывает хук rest_api_init. На нём в имеющийся сервер добавляются свои маршруты.

    3. Обрабатывается REST запрос WP_REST_Server::serve_request( $route ).

      При обработке запроса проверяется доступность текущего маршрута, маршрут обрабатывается, возвращается ответ REST сервера в виде объекта WP_REST_Response.

      При обработке запроса срабатывают следующие полезные хуки (в указанном порядке):

    4. Работа PHP прерывается через die().

Таким образом

За обработку REST запроса отвечает функция rest_api_loaded().

REST запрос выглядит точно также как обычный фронтэнд запрос. До момента установки основного запроса WordPress функцией wp(). В ней как и в обычном фронтэнд запросе устанавливается текущий юзер. Но:

  • НЕ устанавливаются заголовки WP::send_headers().
  • НЕ происходит основного запроса WP::query_posts().
  • НЕ обрабатывается 404 страница WP::handle_404().
  • НЕ вызывается файл template-loader.php, который определяет шаблон страницы.
  • НЕ работает хук редиректов template_redirect.

Заголовки REST ответа ставит REST сервер, также он делает соответствующий запрос в БД или что-угодно еще.