15

I need to disable default routes of WP REST API and add custom routes.

I found this question which helps me to find following answer.

remove_action('rest_api_init', 'create_initial_rest_routes', 99);

However this will also remove any custom content type routes. So instead you may choose to use:

add_filter('rest_endpoints', function($endpoints) {
    if ( isset( $endpoints['/wp/v2/users'] ) ) {
        unset( $endpoints['/wp/v2/users'] );
    }
    // etc
});

But from that way I need to know all the default routes and remove one by one which is not a cleanest way to do.

I would like to know whether there is any cleaner way to achieve that ?

UPDATE 1 :

As per the Chris's suggestion I would add more details to question.

Currently I am using rest_api_init filter to add my custom routes by using register_rest_route method as per the below code which I found on this article.

add_action( 'rest_api_init', function () {
  register_rest_route( 'myplugin/v1', '/sample/', array(
    'methods' => 'GET',
    'callback' => 'my_awesome_func',
  ) );
} );

function my_awesome_func( $data ) {
  return 'somthing';
}

The custom route works well, but unfortunately I can't disable the default routes such as /wp/v2/posts.

My question :

How to unset/disable the default routes while using the rest_api_init filter to register new custom routes ?

Community
  • 1
  • 1
Janith Chinthana
  • 3,792
  • 2
  • 27
  • 54
  • for future reference : Initial question was deviated bit with the UPDATE 1. the code on the initial question will not be working with `rest_api_init` filter. @Chris was answered to the initial question and then I changed it bit, So he will be awarded with bounty. BUT INCASE if SOMEONE LOOKING FOR AN ANSWER FOR `UPDATE 1`, PLEASE REFER MY OWN ANSWER. – Janith Chinthana Mar 22 '17 at 13:52

4 Answers4

10

This question has already accepted answer. But if anybody find this useful. We can easily remove default routes. Add following code in your theme's (child theme's if any) functions.php or in any custom plugin

add_filter('rest_endpoints', function( $endpoints ) {

    foreach( $endpoints as $route => $endpoint ){
        if( 0 === stripos( $route, '/wp/' ) ){
            unset( $endpoints[ $route ] );
        }
    }

    return $endpoints;
});
Shamim Hasan
  • 179
  • 2
  • 9
5

As per the other question, this is the only "clean" way to do it currently. The cleanest way to approach things in Wordpress is by using filters and/or actions - this allows you to interact with core without making changes in core.

By tapping into filters/actions you are also giving other plugins the chance to operate on the filter/action arguments before/after your hook.

If you take a look at class-wp-rest-server.php you can easily look at all available filters and actions related to rest.

You will notice this one in particular:

    /**
     * Filters the array of available endpoints.
     *
     * @since 4.4.0
     *
     * @param array $endpoints The available endpoints. An array of matching regex patterns, each mapped
     *                         to an array of callbacks for the endpoint. These take the format
     *                         `'/path/regex' => array( $callback, $bitmask )` or
     *                         `'/path/regex' => array( array( $callback, $bitmask ).
     */
    $endpoints = apply_filters( 'rest_endpoints', $this->endpoints );

From my research, this is the very last spot to modify (remove, change or add) endpoints, and is the exact purpose of the filter.

As a sidenote, you don't need to do it "one by one" - you could just do $endpoints = [] to start fresh.

Chris
  • 54,599
  • 30
  • 149
  • 186
  • Still I am confusing how & where to use `rest_endpoints` filter. Because I am already using `rest_api_init` filter to add my custom routes. But when ever I used `rest_endpoints` to clear the default routes, it clear up all including the custom once. – Janith Chinthana Mar 13 '17 at 11:41
  • If you dump and die within the `rest_endpoints` filter, do you not see your own custom routes? – Chris Mar 13 '17 at 11:43
  • yes exactly. But I think I am using it on the wrong place or wrong way. I am pretty bad on wordpress. – Janith Chinthana Mar 13 '17 at 11:45
  • BTW, I am using `register_rest_route` method to register custom routes – Janith Chinthana Mar 13 '17 at 11:47
  • Perhaps post everything you have in your question (all the stuff related to rest) so people can help you better – Chris Mar 13 '17 at 11:48
1

REST API Toolbox did the job for me.

We can handle many things via that plugin.

enter image description here

Janith Chinthana
  • 3,792
  • 2
  • 27
  • 54
  • This doesn't really answer your own question? You asked for a way to do it one by one - this plugin just disables all? Or am I missing something – Chris Mar 22 '17 at 13:36
  • When I added this question I thought the code you provided in other question will help to disable the default routes at least one by one. But when use `rest_api_init ` to create custom routes it doesn't work as I expected. But I didn't explain that on the question well. my bad. Actually I need to disable the default routes while using `rest_api_init ` . Hope I am clear enough now. But yes, I agree, that is not describe well enough in the question . – Janith Chinthana Mar 22 '17 at 13:44
  • @Chris No I need to disable all – Janith Chinthana Mar 22 '17 at 13:56
  • Ah ok, I misunderstood - the "one by one" line in your question threw me. I'm glad you found a solution to your answer though – Chris Mar 22 '17 at 15:03
0

I recently had to disable member-only content from appearing in the REST API. Instead of filtering the rest endpoints, I filtered the args used to register the post types:

function dbdb_unset_rest_routes( $args, $post_type ) {
    $allowed_post_types = array( 'page', 'post', 'company', 'job' );
    $allowed_post_types = apply_filters( 'dbdb_unset_rest_routes_types', $allowed_post_types );
    if( in_array( $post_type, $allowed_post_types ) ){
        return $args;
    } else {
         $args['show_in_rest'] = 0;
    }
    return $args;
}
add_filter( 'register_post_type_args', 'dbdb_unset_rest_routes', 20, 2 );

The REST API calls get_post_types() in create_initial_rest_routes() and looks for any post types that have show_in_rest set to true. By filtering the args via the filter: register_post_type_args in register_post_type(), we can filter these routes from showing up in the API.

darrinb
  • 173
  • 1
  • 8