Does something like is_rest() exist

I am starting a bit with the REST API. If I am not completly mislead, the init action hook is also executed when its a REST API request. Now, I want to execute some code only, when it is not a REST API request.

So I was looking for a command like is_rest() in order to do something like

?php
if( ! is_rest() ) echo 'no-rest-request';
?

But I couldn't find something like this. Is there a is_rest() out there?

Topic rest-api Wordpress

Category Web


Just stumbled over the same problem and wrote a simple function is_rest that allows you to check if the current request is a WP REST API request.

<?php

if ( !function_exists( 'is_rest' ) ) {
    /**
     * Checks if the current request is a WP REST API request.
     *
     * Case #1: After WP_REST_Request initialisation
     * Case #2: Support "plain" permalink settings and check if `rest_route` starts with `/`
     * Case #3: It can happen that WP_Rewrite is not yet initialized,
     *          so do this (wp-settings.php)
     * Case #4: URL Path begins with wp-json/ (your REST prefix)
     *          Also supports WP installations in subfolders
     *
     * @returns boolean
     * @author matzeeable
     */
    function is_rest() {
        if (defined('REST_REQUEST') && REST_REQUEST // (#1)
                || isset($_GET['rest_route']) // (#2)
                        && strpos( $_GET['rest_route'], '/', 0 ) === 0)
                return true;

        // (#3)
        global $wp_rewrite;
        if ($wp_rewrite === null) $wp_rewrite = new WP_Rewrite();
            
        // (#4)
        $rest_url = wp_parse_url( trailingslashit( rest_url( ) ) );
        $current_url = wp_parse_url( add_query_arg( array( ) ) );
        return strpos( $current_url['path'] ?? '/', $rest_url['path'], 0 ) === 0;
    }
}

References:


If you need it after init has fired:

defined('REST_REQUEST') && REST_REQUEST

If you need it before init, there are two ways:

Use wp_is_json_request(), or try to infer if it's a REST Request through the URL. Detecting the URL will vary whether the site is using permalinks or plain permalinks.

WooCommerce does it like this, and it's a good solution:

function is_rest_api_request() {
    if ( empty( $_SERVER['REQUEST_URI'] ) ) {
        // Probably a CLI request
        return false;
    }

    $rest_prefix         = trailingslashit( rest_get_url_prefix() );
    $is_rest_api_request = strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) !== false;

    return apply_filters( 'is_rest_api_request', $is_rest_api_request );
}

Maybe not right, but I ended up with

if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
    // Cool API stuff here
}

Feel free to let me know if this isn't right. Trying to make a helpful plugin starter to eventually share: https://gitlab.com/ripp.io/wordpress/plugin-starter


Two options here really,

  1. Check if REST_REQUEST is defined.
  2. Hook into rest_api_init where you wanted to hook into init.

To solve this problem I wrote a simple custom function based on the assumption that if the URI being requested falls under the WordPress site's Rest API URL, then it follows that it's a Rest API request.

Whether it's a valid endpoint, or authenticated, is not for this function to determine. The question is this: is the URL a potential Rest API url?

function isRestUrl() {
    $bIsRest = false;
    if ( function_exists( 'rest_url' ) && !empty( $_SERVER[ 'REQUEST_URI' ] ) ) {
        $sRestUrlBase = get_rest_url( get_current_blog_id(), '/' );
        $sRestPath = trim( parse_url( $sRestUrlBase, PHP_URL_PATH ), '/' );
        $sRequestPath = trim( $_SERVER[ 'REQUEST_URI' ], '/' );
        $bIsRest = ( strpos( $sRequestPath, $sRestPath ) === 0 );
    }
    return $bIsRest;
}

If your $_SERVER['REQUEST_URI'] isn't properly populated, this function will still return false, regardless.

There is no hard-coding of the URL so if you for some reason change your API URL base, this will adapt.


It's a good point by @Milo, the REST_REQUEST constant is defined as true, within rest_api_loaded() if $GLOBALS['wp']->query_vars['rest_route'] is non-empty.

It's hooked into parse_request via:

add_action( 'parse_request', 'rest_api_loaded' );

but parse_request fires later than init - See for example the Codex here.

There was a suggestion (by Daniel Bachhuber) in ticket #34373 regarding WP_Query::is_rest(), but it was postponed/cancelled.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.