The WordPress REST API is great for gaining access to your data from external sites or from front-end JavaScript applications. It is even great for one-off calls you probably used to make via normal WordPress AJAX. However, have you ever wanted or needed to make WordPress REST API calls internally?
What do I mean? I mean being able to make a WordPress REST API call directly within PHP without making an HTTP request. Of course, this would only work if you want the data out of the site on which your code is running.
Why?
You are probably thinking, isn’t this what WP_Query
is for? Why use an internal REST API call to do something that WordPress already allows you to do? Well, the main reason is because WP_Query
returns data in a completely different format than the REST API.
My particular use case for needing this was that I wanted to avoid making an initial HTTP request to fetch the initial data for a JavaScript application. While I could have the JavaScript application make an HTTP request as soon as it loaded, there were a few reasons why an internal REST API call would make more sense:
-
- I could avoid the HTTP request altogether by making an internal query and passing the initial data to the app directly from PHP. This would make my application load much faster.
- I could avoid the lag where a user sees the initial state of the application with no data until the initial HTTP request completes. This would make my application not only be faster but also provide a better user experience. There would be no need for initial loading graphics, time to interaction would be less, etc.
- In the event that users don’t actually interact with the application, no additional HTTP requests are made to the web server. If we made the extra HTTP request, we would end up loading WordPress and all the plugins twice as opposed to just once. Depending on our application’s bounce rate, this could significantly affect the load on the web server.
How to Make an Internal WordPress REST API Call
It isn’t difficult to make an internal REST API call, but it is a bit more involved than your normal WP_Query
usage. Also, keep in mind that the parameters you pass to the REST API are not always the same as what you would pass to WP_Query
. For example, the post_status
query var would become status
when making an API request.
<?php $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); $request->set_query_params( [ 'per_page' => 12 ] ); $response = rest_do_request( $request ); $server = rest_get_server(); $data = $server->response_to_data( $response, false ); $json = wp_json_encode( $data );
Basically, you will start by creating a new instance of a WP_REST_Request
. This takes two parameters: the method and the route. Since you will most likely only be querying data, you’ll probably only use the GET
method for internal requests although you could make POST
requests as well.
Once you have a request, you can call the set_query_params()
method to pass any arguments that you would normally have set in the URL query string. You can set headers as well, but it is important to note that authentication isn’t performed when making internal requests. As such, you will want to make sure that normally protected endpoints aren’t exposed by using this method. Be sure to add any applicable capability checks.
Once you’ve set up your request object, just pass it to the rest_do_request()
function to get a response object.
Finally, get an instance of the REST server by calling rest_get_server()
. Then call the response_to_data()
method on the server and pass it your response object. The second parameter is the embed
option. If false, things like authors and featured images won’t be embedded in the data. If true, they will be embedded. What is returned by doing this is an array containing the data you would normally get in JSON format from the REST API. All you need to do to get actual JSON is to run the data returned through the wp_json_encode()
function.
So what do you think? Have you done anything like this before? If so, I’d love to hear more about your use case!