¿Existe una función como is_rest() en WordPress para detectar peticiones API REST?
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()
?

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.

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

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:

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.

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

Aquí tienes realmente dos opciones,
- Verificar si
REST_REQUEST
está definido. - Enganchar a
rest_api_init
donde querías enganchar ainit
.

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á.

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

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

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!

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.

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/
