• Resolved Andrea Sciamanna

    (@sciamannikoo)


    Hopefully, that’s the right forum where to ask for help.

    As part of a plugin features, I need to provide some REST endpoints.

    However, I need to check first if REST API is active in the running site (since they can be disabled in many ways) and provide feedback to the administrator.

    To do that, I first check if rest_get_server()->get_routes() returns anything.

    If I get nothing, that’s enough for the plugin to know that REST API can’t be used on that site.

    However, if I get something, I suppose I still need to check if I can actually use the REST API.
    To do so, I thought I can simply send a discovery request.

    Using a simple REST client, if I send a GET request to domain.tld/wp-json (where domain.tld is my development site), I get what is documented here.

    However, if, from the same development site, I run the same request via PHP ($response = $this->http->get( get_site_url() . '/wp-json', array( 'timeout' => 10) );) through the plugin, this request times out.
    No matter what timeout value I set, it eventually returns a WP_Error object with cURL error 28: Operation timed out after 10002 milliseconds with 0 bytes received as the error message.

    Am I doing anything wrong?

    Does WP provide a better (server-side) way to check if REST API can be used on the running site?

Viewing 6 replies - 1 through 6 (of 6 total)
  • Thread Starter Andrea Sciamanna

    (@sciamannikoo)

    So, it looks like there was nothing wrong in there, except the fact I needed to add some checks to run the code only on back-end pages.

    I was planning to do that after having confirmed that this works, but apparently, the fact that the code was always running on every request was somehow causing the timeout (though I’ve checked and saw no recursions or anything similar).

    Moderator bcworkz

    (@bcworkz)

    Your code may not be able to see evidence of recursion because each instance is running in its own thread. It’s not really recursion in the traditional sense, though the result is the same — no resolution so the code times out.

    AFAIK, you don’t need an active API to add a routes, only to make use of them. Because the availability of the API can change from time to time, the time to check availability by discovery is just before you wish to use the API. If it’s not available at that point, either do a workaround or notify the user of API failure.

    Thread Starter Andrea Sciamanna

    (@sciamannikoo)

    > you don’t need an active API to add a routes, only to make use of them

    The reason for this whatn’s explained in my post.

    This is the workflow:
    – The plugin creates some “jobs” and send data to an external service, together with an URL (something like /my/endpoint/:jobid)
    – When that job is completed by the external service, it will send a request to the provided URL

    However, if REST API is not active, I need to inform the external service about it, so it won’t try to send these calls (which, instead, will need to be handled manually by the user).

    I hope this explains why I need to run this check.

    Moderator bcworkz

    (@bcworkz)

    I see, thanks for the explanation. The time to check discovery would be just before sending that URL, a process that should be separate from other plugin code. Perhaps triggered by user action or hooked to a specific, strategic WP action. ‘rest_api_init’ where you declare endpoints is not the right time.

    There are several ways to prevent so called “recursion”. (I think “reentrant” might be a more accurate term for this phenomena??) Checking is_admin() like you’ve done can be one way. Setting a constant or global value similar to how DOING_AJAX works is another. Action callbacks removing themselves from the call stack is another approach.

    It’s not always easy to recognize when you’ve setup an infinite reentrant or recursive condition until your code unexpectedly times out. Even then it’s often difficult to grasp what’s really happening. If you have some reliable techniques to draw upon that prevent infinite reentrance, it’s not necessary to fully grasp how it happens as long as you can recognize the signs and know how to prevent it ??

    Thread Starter Andrea Sciamanna

    (@sciamannikoo)

    > The time to check discovery would be just before sending that URL

    I like the idea: I’ll use this approach!

    As for the “reentrant”, I ended up by checking if REST_REQUEST is defined (which should be enough) and if it’s set to true (probably redundant).

    Checking against the constant seems to be enough to avoid the problem and also makes the code more readable. Checking with is_admin, even if it may work, may look a bit out of context.

    I’ve seen some discussions (I lost the URLs) where users were asking for a way to detect a REST request (as you wrote, pretty much like DOING_AJAX).
    It looks like there is not much will to do so, which makes me wonder if that constant is there to stay ??

    Moderator bcworkz

    (@bcworkz)

    There’s a REST_REQUEST constant set? I clearly do not use the API much ?? I certainly have accidentally caused infinite reentrant or recursive calls enough times to have developed ways to prevent it.

    Once functionality goes into core, it’s not easily removed. Core devs are very cognizant of reverse compatibility needs. There’s a long process in deprecating functions to ensure we are adequately warned before the functionality is fully removed. I’m not sure how a constant could be deprecated in a similar way though. I cannot speak for core devs, but I doubt there is any reason to worry about REST_REQUEST going away.

    It looks like many if not all plugins that add their own endpoints rely on REST_REQUEST. If it were to suddenly go away, there would be a lot of broken plugins!

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Trying to check if REST API is active from a plugin, causes a time out’ is closed to new replies.