REST API Discovery
Discovery is any actions aimed at determining how the REST API works. For example:
- What URL the root directory of the API is located at.
- What schema a resource has.
- What parameters a specific endpoint has.
- Which plugins/themes have extended (use) the REST API.
Typically, all forms of discovery boil down to reading the route schema or the schema of the entire WP API, but to read such a schema, one needs to determine (discover) what the root URL of the REST API is. In PHP, the root URL can be obtained using the function rest_url().
Discovery via Link in the Response Header
The recommended way to discover the URL of the REST API is to send a HEAD request to any page of the site and check if there is a Link: parameter in the response. The REST API automatically adds the Link parameter to the response headers for all pages on the frontend.
Link: <http://example.com/wp-json/>; rel="https://api.w.org/"
The link specified in the parameter leads to the root route of the REST API (/
). It can be used for further discovery of routes.
For sites with pretty permalinks disabled, /wp-json/
is not automatically processed in WordPress. In such cases, the link to the REST API will look like this:
Link: <http://example.com/?rest_route=/>; rel="https://api.w.org/"
Discovery via <link> Meta Tag
For clients that cannot read HEADER response headers (which parse HTML or run in a browser), the URL for the REST API can be obtained in the HTML meta tag link in the <head> section of the document. Such a meta tag is also added to all pages on the frontend.
<link rel='https://api.w.org/' href='http://example.com/wp-json/' />
In Javascript, this link can be obtained through the DOM:
// jQuery version var api_root = jQuery( 'link[rel="https://api.w.org/"]' ).attr( 'href' ); // Native 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;
This discovery is also valid for discovering Atom/RSS feeds. Thus, this code can be adapted for this need.
Discovery via RSD
For clients supporting XML-RPC discovery, it may be more convenient to obtain the link to the REST API through XML. Here, two steps need to be taken:
First step: find the RSD endpoint (URL), which is also located in the <link> element in the <head> section on any frontend page:
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://example.com/xmlrpc.php?rsd" />
Second step: obtain the XML code from the discovered link and parse it. It looks something like this:
<?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>
The element with the link to the REST API will always have the attribute name="WP-API"
.
RSD discovery is NOT a recommended method because it is the most complex; one must first find the link to RSD, then parse the code from that link, and only then obtain the URL of the REST API.
Whenever possible, it is advisable to avoid such RSD discovery!
Discovery of Available Authentication Methods
Discovery also allows determining what authentication methods are available in the REST API. The response from the main route of the REST API /wp-json/ contains an object that fully describes the API. In this object, under the key authentication
, there is data about possible authorization methods in the 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" } } }
For more details on authentication in the REST API, read the relevant section.
Discovery of Existing Extensions
Once the REST API is discovered, it is necessary to know what the API supports. The available extensions in the API can be found from the response to the root route of the REST API /wp-json/
. There, under the key namespaces
, all existing API extensions are listed:
For WP versions from 4.4 to 4.6, only the basic extension oEmbed is available (the full API described in this guide is not yet available).
{ "name": "Test Site", "namespaces": [ "oembed/1.0/" ] }
Starting from WP 4.7, all APIs are available; thus, one can see the new extension wp/v2:
{ "name": "Test Site", "namespaces": [ "wp/v2", "oembed/1.0/" ] }
Before attempting to use any of the endpoints, one must ensure that it is supported in the API; for this, check for the presence of the required namespace, for example, wp/v2.
WordPress 4.4 includes API infrastructure for all sites but does not include core endpoints under wp/v2. Core endpoints work starting from WordPress 4.7.
This same mechanism can be used to determine the support for REST extensions by plugins. For example, suppose a plugin registers the following route:
register_rest_route( 'testplugin/v1', '/testroute', array( /* ... */ ) );
Then, the API data will include a new extension testplugin/v1:
{ "name": "Test Site", "namespaces": [ "wp/v2", "oembed/1.0/", "testplugin/v1" ] }