¿Existe una función como is_rest() en WordPress para detectar peticiones API REST?

20 mar 2016, 14:48:48
Vistas: 18.9K
Votos: 34

Estoy empezando un poco con la API REST. Si no estoy completamente equivocado, el hook de acción init también se ejecuta cuando es una petición de la API REST. Ahora, quiero ejecutar cierto código solo cuando no sea una petición de la API REST.

Así que estaba buscando un comando como is_rest() para hacer algo como:

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

Pero no pude encontrar algo así. ¿Existe un is_rest()?

2
Comentarios

¿Podrías elaborar sobre lo que quieres hacer cuando no es una petición REST? El tipo de solicitud no se determina hasta el análisis de la consulta, que ocurre después de init. También ten en cuenta que partes de la API pueden ser usadas internamente en solicitudes que no son peticiones REST, así que corres el riesgo de romper algo si dependes de esa detección.

Milo Milo
20 mar 2016 18:39:42

Muchas gracias a ambos. @birgire: ¿Podrías publicar esto como una respuesta, así puedo marcarla? Básicamente, es la respuesta a mi pregunta :)

websupporter websupporter
21 mar 2016 08:58:49
Todas las respuestas a la pregunta 8
1
22

Es un buen punto el de @Milo, la constante REST_REQUEST está definida como true dentro de rest_api_loaded() si $GLOBALS['wp']->query_vars['rest_route'] no está vacío.

Está enganchada a parse_request mediante:

add_action( 'parse_request', 'rest_api_loaded' );

pero parse_request se ejecuta más tarde que init - Puedes verlo en el Codex aquí.

Hubo una sugerencia (de Daniel Bachhuber) en el ticket #34373 sobre WP_Query::is_rest(), pero fue pospuesta/cancelada.

21 mar 2016 16:34:39
Comentarios

#42061 podría agregar wp_is_rest_request() o wp_doing_rest().

Ian Dunn Ian Dunn
10 mar 2020 21:40:35
3
22

Acabo de toparme con el mismo problema y escribí una función simple is_rest que te permite verificar si la solicitud actual es una solicitud de la API REST de WordPress.

<?php

if ( !function_exists( 'is_rest' ) ) {
    /**
     * Verifica si la solicitud actual es una solicitud de la API REST de WordPress.
     *
     * Caso #1: Después de la inicialización de WP_REST_Request
     * Caso #2: Soporte para ajustes de enlaces permanentes "simples" y verifica si `rest_route` comienza con `/`
     * Caso #3: Puede ocurrir que WP_Rewrite no esté inicializado aún,
     *          así que haz esto (wp-settings.php)
     * Caso #4: La ruta URL comienza con wp-json/ (tu prefijo REST)
     *          También soporta instalaciones de WP en subcarpetas
     *
     * @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;
    }
}

Referencias:

18 oct 2018 20:02:11
Comentarios

No entendí lo que hace el #3.

kodfire kodfire
20 jun 2022 11:43:54

Esta es la mejor función para WordPress jamás escrita en stackoverflow. Necesitaba usarla para un hook pre_get_posts que ignora las solicitudes REST y funcionó perfectamente.

Philip Philip
25 ene 2023 10:12:46

¡Ah! ¡Ahora entiendo qué está mal con un plugin popular que copió tu código del 2018 pero nunca incorporó el cambio (muy importante) que hiciste en 2022! Bien hecho :-) Gracias por la actualización.

Gwyneth Llewelyn Gwyneth Llewelyn
24 sept 2023 14:28:36
0
13

Si lo necesitas después de que se haya ejecutado init:

defined('REST_REQUEST') && REST_REQUEST

Si lo necesitas antes de init, hay dos formas:

Usar wp_is_json_request() (Introducido en WordPress 5.0), o intentar inferir si es una solicitud REST a través de la URL. Detectar la URL variará si el sitio usa enlaces permanentes o enlaces permanentes simples.

WooCommerce lo hace así, y es una buena solución:

function is_rest_api_request() {
    if ( empty( $_SERVER['REQUEST_URI'] ) ) {
        // Probablemente una solicitud CLI
        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 );
}
22 ene 2020 15:46:34
1

Aquí tienes realmente dos opciones,

  1. Verificar si REST_REQUEST está definido.
  2. Enganchar a rest_api_init donde querías enganchar a init.
10 mar 2019 22:28:26
Comentarios

Si estás utilizando la versión 4.4.0+ de WP (que probablemente sí), esta es la respuesta correcta.

Mat Lipe Mat Lipe
5 oct 2020 22:54:38
0

Para resolver este problema escribí una función personalizada simple basada en la suposición de que si la URI solicitada cae bajo la URL de la API Rest del sitio WordPress, entonces es una solicitud de la API Rest.

Si es un endpoint válido o está autenticado, no es responsabilidad de esta función determinarlo. La pregunta es esta: ¿la URL es una URL potencial de la API Rest?

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;
}

Si tu $_SERVER['REQUEST_URI'] no está correctamente poblado, esta función seguirá devolviendo false, independientemente.

No hay codificación fija de la URL, por lo que si por alguna razón cambias la URL base de tu API, esta se adaptará.

8 sept 2017 11:29:35
3

Puede que no sea lo correcto, pero terminé con

if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
    // Cosas interesantes de la API aquí
}

No dudes en hacerme saber si esto no es correcto. Estoy intentando crear un plugin inicial útil para compartir eventualmente: https://gitlab.com/ripp.io/wordpress/plugin-starter

30 may 2019 18:36:41
Comentarios

Creo que esto fallaría si no tuvieras los pretty permalinks activos.

websupporter websupporter
10 jun 2019 12:34:07

Definitivamente tienes razón

Charly Charly
11 jun 2019 17:25:40

Ok, requiere pretty permalink... pero ¿quién no lo quiere!!!? Esto me parece la forma más segura de hacerlo. Todas las demás soluciones son elegantes, pero con el tiempo, si quieres que tu código siga funcionando en versiones posteriores de WP... ¡esto me parece una forma segura!

Antony Gibbs Antony Gibbs
30 jul 2019 09:21:39
1

Con WordPress 6.5, el núcleo proporciona una función wp_is_rest_endpoint para determinar de manera confiable si la solicitud actual es una solicitud dirigida a un endpoint REST.

También existe otra función wp_is_serving_rest_request para verificar si realmente se está atendiendo una solicitud de la API REST. Si la utilizas, asegúrate de llamarla después de la acción parse_request, ya que siempre devolverá false antes de eso.

15 may 2024 08:58:03
Comentarios

Mejor respuesta hasta ahora

Kuba Niewiarowski Kuba Niewiarowski
20 sept 2024 18:52:08
0

Puedes usar wp_is_json_request() como se muestra a continuación:

if ( wp_is_json_request() ) {
    // haz lo que necesites aquí
}

Asegúrate de configurar Accepts o Content-Type como application/json de lo contrario wp_is_json_request() devolverá false.

Más documentación: https://developer.wordpress.org/reference/functions/wp_is_json_request/

5 nov 2022 11:03:28