WordPress REST API was introduced into the core in version 4.7 (Vaughan) in December 2016. Like any other significant change made on the WP core, it was fiercely debated (at the moment, July 2018, Gutenberg is the subject of such a debate/controversy). In the end, nothing happened. Those who didn’t care about the REST API still don’t care. Those who do care made some apps, integrations, plugins and other cool projects.

We do care about the REST API and utilize it when building WP powered SaaSes. It’s stable, fast, easy to work with, fits snugly into WP and in most cases well documented. If you don’t know what REST API is this is probably not the post for you but check out what REST API is (video and text) and maybe you’ll use it in your next project.

Route? Endpoint? Isn’t it all the same?

No, it’s not the same. The difference is subtle to most people, and they use terms route and endpoint interchangeably, but it’s not that complicated. The route is more or less the URL. It’s the “name” used to access an endpoint. On a single route, you can have multiple endpoints because what endpoint you use depends on the HTTP request type you use. GET, POST, PUT or DELETE can, and usually do serve different purposes. Accessing yoursite.com/wp-json/v2/posts/1 via GET will get you details for post with ID #1. Using DELETE on the same route will call a different endpoint (or function if you’d like) that deletes that post. The official REST API handbook has more info on this subject so dive in for details.

Why would I remove default WP REST API endpoints or routes?

As we discussed in the article about removing default rewrite rules – there are a hundred reasons.
“It will make WordPress faster because it doesn’t have to parse all those endpoints.” is still something I don’t agree with and believe the gain will be less than a millisecond but it can’t hurt.

You like to keep things clean and since you’re not using the REST API – why have API routes? Sure, makes sense. But in that case, use a plugin to disable REST API completely.

And then there’s the reason we disable default routes (and endpoints). We heavily use custom REST API endpoints but don’t need the default ones. Hence, it’s nice to keep things lean and clean. It also can’t hurt security wise as we’re exposing fewer pieces of data to the harsh, outside world.

Show me the default API endpoints

The endpoint reference is available in the REST API handbook. More or less any piece of data that’s publically available will be available through REST API as well. An example request to demo.wp-api.org/wp-json/wp/v2/posts will show ten posts in JSON format. If you want a human-readable version of that response you’ll need to decode the JSON response. Same goes for pages, categories and other data structures. The data structure and endpoints are very similar as you can see if you browse through the reference.

The other way to see default routes is to add this code to your theme’s functions.php file and then open yoursite.com/wp-json/. Enable pretty links if you haven’t already.

add_filter( 'rest_endpoints', 'show_default_endpoints' );
 
function show_default_endpoints( $endpoints ) { 
  var_export( array_keys( $endpoints ) );
  die;
}

It shows the default 31 REST endpoints. The number is, of course, susceptible to change as new core functionalities are added. And it’ll be different if you have any plugins that add custom endpoints.

Removing the default endpoints

The code above requires minimal change. Return an empty array, and all endpoints are gone.

add_filter( 'rest_endpoints', 'remove_default_endpoints' );
 
function remove_default_endpoints( $endpoints ) { 
  return array( );
}

“All endpoints” includes your custom endpoints too, so it’s wise not to delete them. Here’s an easy way to keep them active:

add_filter( 'rest_endpoints', 'remove_default_endpoints_smarter' );
 
function remove_default_endpoints_smarter( $endpoints ) { 
  $prefix = 'your_custom_endpoint_prefix';

  foreach ( $endpoints as $endpoint => $details ) {
    if ( !fnmatch( '/' . $prefix . '/*', $endpoint, FNM_CASEFOLD ) ) {
      unset( $endpoints[$endpoint] );
    }
  }

  return $endpoints;
}

Just skip endpoints with your custom prefix and keep them in the array. Don’t forget to return the array.

Customizing the REST URL prefix

Custom endpoints, despite being custom use the same prefix as the default endpoints. They look like mysite.com/wp-json/custom-endpoint/. Maybe you find that ugly or don’t like default stuff. Changing it is a matter of one line of code. For testing purposes place the code below in theme’s functions.php and after saving open Dashboard – Settings – Permalinks to flush rewrite rules.

add_filter( 'rest_url_prefix', 'rest_url_prefix' );

function rest_url_prefix( ) {
  return 'api';
}

With the filter above your endpoints will be mysite.com/api/custom-endpoint/ and opening the old mysite.com/wp-json/custom-endpoint/ URL will yield a 404 error.

Make sure you include a version number in your custom endpoints as a prefix is not added automatically by WP. A version number prefix ensures changes down the road don’t break clients that use the old endpoints. Just include the version prefix when calling the register_rest_route() to get something like mysite.com/api/v1/custom-endpoint/ and keep all your endpoints behind that “v1” so you can have “v2” etc later on.

Test your changes

Removing or modifying REST API routes and endpoints won’t make any difference on 98% of WP sites. “Why?” – Because they don’t use the REST API at all. But if yours does please make sure you test the connected apps because, as with everything, changes can breaking things. And it’s better to spot a bug today than tomorrow.

Leave a Reply

Your email address will not be published. Required fields are marked *