REST Request Load in WordPress

A 90% REST request is handled the same way as a frontend request. The process starts with index.php file as well. The request parameter rest_route=route is set via rewrite rules (user-friendly URLs).

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

The process of loading a REST request looks like this:

	// sets WP_USE_THEMES constant

		// WP CORE See
		require_once dirname(__FILE__) . '/wp-load.php';

		// In the process of loading the core, a hook `parse_request` is created
		// and it is triggered in the `wp()` function
		add_action( 'parse_request', 'rest_api_loaded' );

		// Sets the main WordPress query.
		// Makes a request and determines which page is loading.
		// When the `parse_request` hook kicks in, control is passed
		// to the rest_api_loaded() function, which aborts PHP via die.
		// See
		wp(); // См. WP::main()

Explanation of wp() and parse_request hook

The wp() function calls the WP::main() method, it does the following in order:

  1. Calls WP::init().

    This method sets the current user for normal (non-REST) requests. See wp_get_current_user().

    Later (if it's a REST request), on rest_authentication_errors authentication hook the authorized user will be nulled if the nonce code is wrong. See also:

  2. Calls WP::parse_request().

    This method sets the parameters of the current query $wp->query_vars.

  3. REST Running - rest_api_loaded().

    At the end of WP::parse_request(), the parse_request hook is triggered and it runs the rest_api_loaded() function:

    add_action('parse_request', 'rest_api_loaded' );

    ``rest_api_loaded()`` checks the query parameter ``$GLOBALS['wp']->query_vars['rest_route']``. If it's a REST request, it starts the REST logic (query logic for normal pages ends here).
    1. Sets the define('REST_REQUEST', true ) constant.

    2. Starts the REST server rest_get_server().

      The rest_api_init hook is triggered on startup. It adds routes to the existing server.

    3. the REST request WP_REST_Server::serve_request( $route ) is processed.

      When the request is processed, the current route is checked for availability, then the route is processed, and then the REST server response is returned as a WP_REST_Response object.

      When the request is processed, the following useful hooks are triggered (in that order):

    4. PHP is interrupted by die().


rest_api_loaded() function is fully responsible for processing REST request.

The REST request looks exactly like a normal frontend request. Until setting the main WordPress request by wp() function. It sets the current user as in a normal frontend request. But:

  • The headers WP::send_headers() are NOT set.
  • The main query WP::query_posts() does NOT happen.
  • The WP::handle_404() does NOT handle the 404 page.
  • The template-loader.php file is NOT calling (it defines the page template).
  • The redirect template_redirect hook is NOT triggering.

The REST server is setups response headers; it also makes a corresponding request to the database or do any other stuff.

This Note embeded into: How WordPress Core Loads