vendredi 25 septembre 2026

À propos

Contact

Headless & API

Créer un endpoint REST sur mesure avec register_rest_route()

Tutoriel pas à pas pour concevoir un endpoint REST WordPress personnalisé, sécurisé et validé, avec register_rest_route() dans un plugin.

Par Clément Hadrot • 15 juillet 2020 • 5 min de lecture • Aucun commentaire
Créer un endpoint REST sur mesure avec register_rest_route()

L’API REST native de WordPress couvre les besoins standards : articles, pages, médias, taxonomies. Mais un projet headless réclame presque toujours des routes sur mesure, adaptées à une logique métier précise, comme récupérer les articles « à la une », calculer un résumé de statistiques, ou exposer une ressource qui n’a pas d’équivalent direct dans le cœur.

C’est exactement le rôle de la fonction register_rest_route(). Elle permet de déclarer une route entièrement personnalisée dans un plugin, avec son propre espace de noms, sa logique de traitement et ses règles de sécurité. Ce tutoriel construit, étape par étape, un endpoint qui retourne les articles mis en avant d’un site.

Où et quand enregistrer la route

L’enregistrement doit se faire sur le hook rest_api_init, jamais avant, sous peine d’erreurs silencieuses. Voici le squelette de base, à placer dans un plugin dédié plutôt que dans functions.php d’un thème, pour que la fonctionnalité survive à un changement de thème :

add_action( 'rest_api_init', function () {
    register_rest_route( 'wpmoderne/v1', '/articles-a-la-une', array(
        'methods'             => WP_REST_Server::READABLE,
        'callback'            => 'wpmoderne_get_articles_a_la_une',
        'permission_callback' => '__return_true',
    ) );
} );

Le namespace wpmoderne/v1 est un choix volontaire : préfixer avec le nom de votre projet ou plugin évite toute collision avec wp/v2 ou avec les routes d’un autre plugin. Le suffixe /v1 permet de faire évoluer la route plus tard sans casser les intégrations existantes : le jour où la structure change en profondeur, on publie simplement /v2 en parallèle.

Écrire le callback

Le callback reçoit un objet WP_REST_Request et doit renvoyer soit un WP_REST_Response, soit un WP_Error en cas de problème. Voici l’implémentation de notre endpoint :

function wpmoderne_get_articles_a_la_une( WP_REST_Request $request ) {
    $query = new WP_Query( array(
        'post_type'      => 'post',
        'posts_per_page' => 5,
        'meta_key'       => 'a_la_une',
        'meta_value'     => '1',
    ) );

    $articles = array();
    foreach ( $query->posts as $post ) {
        $articles[] = array(
            'id'    => $post->ID,
            'titre' => get_the_title( $post ),
            'lien'  => get_permalink( $post ),
        );
    }

    return new WP_REST_Response( $articles, 200 );
}
L'essentiel à retenir : Un namespace personnalisé évite les collisions avec wp/v2 ; permission_callback ne doit jamais être ignoré ; validate_callback et sanitize_callback sécurisent les arguments

Le permission_callback : la règle numéro un

C’est le point le plus souvent négligé, et le plus critique en matière de sécurité. Depuis WordPress 5.5, ne pas définir permission_callback déclenche même un message d’avertissement dans les logs, précisément pour forcer les développeurs à y réfléchir.

Trois cas de figure typiques :

  • Route publique en lecture : permission_callback peut valoir __return_true, en toute connaissance de cause, uniquement si la donnée exposée est réellement publique
  • Route réservée aux utilisateurs connectés : utiliser une fonction qui vérifie is_user_logged_in() ou une capacité précise avec current_user_can()
  • Route d’écriture : toujours vérifier une capacité adaptée à l’action, jamais un simple is_user_logged_in() qui n’exclut pas les rôles trop permissifs
'permission_callback' => function () {
    return current_user_can( 'edit_posts' );
},

Un __return_true posé « pour tester » a une fâcheuse tendance à survivre jusqu’en production. Sur nos projets, chaque route fait l’objet d’une revue explicite de son permission_callback avant la mise en ligne, sans exception.

Valider et nettoyer les arguments

Pour une route qui accepte des paramètres, l’argument args permet de déclarer un schéma de validation et de nettoyage, exécuté automatiquement par WordPress avant que le callback ne soit appelé :

register_rest_route( 'wpmoderne/v1', '/articles-a-la-une', array(
    'methods'             => WP_REST_Server::READABLE,
    'callback'            => 'wpmoderne_get_articles_a_la_une',
    'permission_callback' => '__return_true',
    'args'                => array(
        'limite' => array(
            'default'           => 5,
            'sanitize_callback' => 'absint',
            'validate_callback' => function( $value ) {
                return is_numeric( $value ) && $value <= 20;
            },
        ),
    ),
) );

Cette séparation est importante : validate_callback rejette la requête si la valeur est incorrecte, tandis que sanitize_callback nettoie la valeur avant utilisation. Les deux se complètent et ne doivent pas être confondus.

Gérer les erreurs proprement

Quand une requête ne peut pas aboutir, renvoyez un WP_Error plutôt qu’un tableau vide silencieux : le frontend saura distinguer une absence de résultat d’une véritable erreur.

if ( empty( $articles ) ) {
    return new WP_Error(
        'aucun_article',
        'Aucun article à la une pour le moment.',
        array( 'status' => 404 )
    );
}

En résumé

register_rest_route() donne un contrôle total sur la logique métier exposée à un frontend headless, à condition de respecter trois règles simples : un namespace propre à votre projet, un permission_callback pensé pour chaque route et jamais laissé par défaut, et une validation systématique des arguments reçus. Ces bonnes pratiques, appliquées dès le premier endpoint, évitent la plupart des failles de sécurité qu’on retrouve encore sur des projets headless bâclés.

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