Le WordPress d'aujourd'hui, décodé pour les développeurs

Headless & API

Derrière une route REST, le cycle de chargement de WordPress tourne encore

Une requête vers une route REST déclenche les mêmes hooks du cœur qu'une page rendue classiquement. Comprendre cet ordre aide à déboguer un comportement inattendu.

Par Clément Hadrot • 25 juin 2024 • 4 min de lecture • Aucun commentaire
Derrière une route REST, le cycle de chargement de WordPress tourne encore

« Une route REST, c’est plus léger qu’une page complète, non ? » Cette hypothèse, répandue chez les développeurs qui découvrent le développement headless, mérite d’être corrigée : une requête vers /wp-json/ déclenche le chargement complet du cœur de WordPress, exactement comme le ferait l’affichage d’une page classique. Ce que la route REST évite, c’est uniquement le rendu du gabarit de thème, pas l’initialisation du logiciel dans son ensemble.

Comprendre précisément quels hooks s’exécutent, et dans quel ordre, avant qu’une réponse REST ne soit renvoyée permet de déboguer efficacement un comportement inattendu : un champ manquant, une donnée non filtrée comme prévu, ou une extension qui semble interférer sans lien apparent avec la route concernée.

L’ordre réel d’exécution

Une requête HTTP vers une route de l’API REST traverse la même séquence d’amorçage que n’importe quelle autre requête WordPress, avec quelques hooks spécifiques qui s’ajoutent en cours de route :

  1. plugins_loaded : toutes les extensions actives sont chargées, y compris celles sans lien apparent avec l’API REST.
  2. init : les types de contenus personnalisés, les taxonomies et les routes REST elles-mêmes sont enregistrés via register_post_type() et consorts.
  3. rest_api_init : ce hook spécifique se déclenche uniquement lorsque la requête entrante cible effectivement l’API REST, et sert de point d’ancrage privilégié pour register_rest_route().
  4. Résolution de la route, exécution du permission_callback, puis du callback principal.
L'essentiel à retenir : plugins_loaded, init et rest_api_init s'exécutent dans un ordre précis ; Une requête REST charge l'intégralité du cœur, pas seulement le routeur ; Un plugin mal conditionné peut interférer avec une réponse REST sans lien apparent

Ce que cet ordre explique concrètement

Un filtre appliqué deux fois sans raison apparente

Un développeur qui accroche un filtre the_content à la fois dans le rendu classique et dans le traitement d’une route REST personnalisée peut observer une transformation appliquée deux fois si le callback de la route appelle indirectement une fonction qui exécute déjà ce filtre, comme get_the_content() suivi d’un traitement manuel équivalent. Comprendre que init précède l’exécution du callback de route aide à localiser où ce filtre a réellement été accroché et pourquoi il s’applique dans ce contexte précis.

Une extension qui modifie une réponse REST sans y toucher directement

Une extension de sécurité activée sur le site, qui bloque certaines requêtes selon leur en-tête User-Agent dès le hook init, peut empêcher une route REST légitime de répondre correctement, alors que rien dans le code de cette route ne semble concerné. Le fait que plugins_loaded et init s’exécutent avant même que la route ne soit identifiée explique pourquoi ce type d’interférence, en apparence sans rapport, doit systématiquement figurer dans la liste des causes à vérifier.

Utiliser cet ordre pour déboguer efficacement

Ajouter des points de trace à chaque étape clé du cycle permet de confirmer précisément où un comportement diverge de l’attendu :

add_action( 'plugins_loaded', function () {
    error_log( 'plugins_loaded : ' . $_SERVER['REQUEST_URI'] );
} );

add_action( 'rest_api_init', function () {
    error_log( 'rest_api_init declenche' );
} );

add_filter( 'rest_pre_dispatch', function ( $result, $server, $request ) {
    error_log( 'route resolue : ' . $request->get_route() );
    return $result;
}, 10, 3 );

Cette instrumentation temporaire, à retirer une fois le diagnostic posé, révèle rapidement si un plugin tiers interfère avant même que la route personnalisée n’entre en jeu, un cas fréquent quand plusieurs extensions de sécurité ou de cache coexistent sur la même installation.

Ce que cela signifie pour la conception

  • Une route REST ne dispense jamais d’auditer l’ensemble des extensions actives sur l’installation, même sans lien apparent avec l’API.
  • Le hook rest_api_init reste le point d’ancrage le plus fiable pour enregistrer des routes personnalisées, plutôt que init seul.
  • Un comportement inattendu sur une route REST mérite d’être vérifié en remontant tout le cycle, pas seulement le code du callback lui-même.

Une route REST qui répond en apparence de façon isolée reste, sous le capot, un point d’arrivée d’un cycle de chargement complet. Ignorer ce cycle en cas de comportement anormal revient à chercher une clé perdue uniquement sous le lampadaire, là où la lumière est la plus commode.

En résumé

La légèreté apparente d’une réponse REST ne doit pas masquer la réalité de son exécution : le cœur de WordPress tourne intégralement derrière chaque requête, avec ses hooks, ses extensions actives et ses filtres. Garder cet ordre précis en tête simplifie considérablement le débogage d’un comportement qui semble, à première vue, n’avoir aucun lien avec la route concernée.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi