I want to create a REST API endpoint for a wordpress site where I can get a JSON response for different queries. I have tried the tutorial here, but I cant seem to figure out how it works. Do I need to register all the query variables to use them? Also I think it would be best to use the add_rewrite_endpoint but I have not used any of this before. So I would like to know how to use that function in the code below.

I want to send a query like <url>/wp-api/version where it will return the wordpress version number. But right now its not taking any queries other than ‘pugs’. I am not sure what exactly is going on with the regex so I didn’t change that. Can someone please help me understand this?

class WP_API_Endpoint{

//  Hook WordPress
public function __construct(){
    add_filter('query_vars', array($this, 'add_query_vars'), 0);
    add_action('parse_request', array($this, 'sniff_requests'), 0);
    add_action('init', array($this, 'add_endpoint'), 0);
}   

/*  
    Add public query vars
    @param array $vars List of current public query vars
    @return array $vars     
*/
public function add_query_vars($vars){
    $vars[] = '__wp-api';
    $vars[] = 'pugs';
    return $vars;
}

//  Add API Endpoint
public function add_endpoint(){
    add_rewrite_rule('^wp-api/pugs/?([0-9]+)?/?','index.php?__wp-api=1&pugs=$matches[1]','top');
}

/*  
    Sniff Requests
    This is where we hijack all API requests
    If $_GET['__api'] is set, we kill WP and serve our data
    @return die if API request
*/
public function sniff_requests(){
    global $wp;
    if(isset($wp->query_vars['__wp-api'])){
        $this->handle_request();
        exit;
    }
}

protected function get_wp_version() {
    return get_bloginfo('version');
}

//  This is where we handle incoming requests
protected function handle_request(){

    global $wp;

    $pugs = $wp->query_vars['pugs'];
    if($pugs)
        $this->send_response('wp-version', $this->get_wp_version());
    else
        $this->send_response('Something went wrong with the pug bomb factory');

}

//  This sends a JSON response to the browser
protected function send_response($key, $val){
    $response[$key] = $val;
    header('content-type: application/json; charset=utf-8');
    echo json_encode($response)."\n";
    exit;
}
}
new WP_API_Endpoint();

1
1

First thing is the add rewrite rule function. You have –

add_rewrite_rule('^wp-api/pugs/?([0-9]+)?/?','index.php?__wp-api=1&pugs=$matches[1]','top');

wp-api/pugs/?([0-9]+) this means, when you request <url>/wp-api/pugs/123, you will get a query variable pugs with parameter 123.

$var = get_query_var('pugs'); // = 123

Now, you don’t really need pugs in the url as per you needs. So, just remove it this way. Also, the matching regex should not be number only. so the changed code would be –

add_rewrite_rule('^wp-api/?([^/]+)?/?','index.php?__wp-api=1&pugs=$matches[1]','top');

Final usage is:

protected function handle_request(){

    global $wp;

    $pugs = $wp->query_vars['pugs'];

    // <url>/wp-api/version/
    if( 'version' == $pugs )
        $this->send_response( 'wp-version', $this->get_wp_version() );


    // <url>/wp-api/something/
    elseif( 'something' == $pugs )
        $this->send_response( 'something', 'something' );

    else
        $this->send_response( 'Something went wrong with the pug bomb factory');
}

Leave a Reply

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