Routes entièrement personnalisées dans l’API REST de WordPress

WordPress fournit nativement une très puissante API REST, mais qui vient avec son lot de contraintes, qu’il est parfois compliqué de contourner.

Si nos routes doivent correspondre à un format précis, il peut être nécessaire de mettre en place les actions ci-dessous dans votre thème ou vos plugins.

La première modification à apporter, si vous souhaitez exposer vos URL, est de renommer le préfixe /wp-json pour /api par exemple.

add_filter('rest_url_prefix', 'pleb_rest_url_prefix');
function pleb_rest_url_prefix( $slug ) { 
    return 'api'; 
}

 

Par défaut, tous les endpoints de l’API REST sont exposés sur la route racine. Vous pouvez lister toutes les routes enregistrées en vous rendant à l’URL /wp-json (ou /api si vous avez réalisé l’étape précédente)

Pour masquer ces routes au public sans désactiver les fonctionnalités, vous pouvez intervenir sur le hook rest_index, en vidant la liste des routes et des namespaces à afficher :

add_filter('rest_index', 'pleb_empty_rest_index', 9999, 1);
function pleb_empty_rest_index($response){
    $data = $response->get_data();
  
    $data['namespaces'] = [];
    $data['routes'] = [];
  
    return $data;
}

 

Si vous voulez complètement désactiver l’API REST, vous pouvez vous greffer au hook rest_endpoints :

add_filter('rest_endpoints', 'pleb_remove_rest_endpoints');
function pleb_remove_rest_endpoints( $endpoints ) {
    return [];
}

Mais attention, cette action peut provoquer des effets indésirables sur le fonctionnement interne du CMS, et elle supprime également les endpoints que vous avez pu créer vous-même.

Pour filtrer les endpoints à conserver, vous pouvez procéder comme ceci :

add_filter('rest_endpoints', 'pleb_remove_rest_endpoints');
function pleb_remove_rest_endpoints( $endpoints ) {
    foreach ($endpoints as $endpoint => $details){
        if( !in_array($endpoint, [
            '/endpoint/a/conserver',
            '/wp/v2/posts/(?P<id>[\d]+)',
        ]) ){
            unset( $endpoints[$endpoint] );
        }
    }
    return $endpoints;
}

 

Nativement, la création de routes REST (par la fonction register_rest_route par exemple) vous contraint à déclarer un namespace, ce qui ajoute un nouvel élément dans l’URL.

Par conséquent, les routes déclarées par cette méthode auront le format /apiprefix/namespace/endpoint

Si vous souhaitez vous passer de ce namespace, afin d’accéder à vos endpoints directement après le préfixe /api, vous pouvez vous baser sur la classe WP_REST_Server, en utilisant la méthode register_route

Pour cela, on peut se greffer au hook rest_api_init, qui fournit une instance de WP_REST_Server, et lui ajouter nos propres routes, en indiquant la/les méthodes REST à écouter :

add_action('rest_api_init', function($server){
    $server->register_route('custom-route-post', '/custom-route-post', [
        'methods'  => 'POST',
        'callback' => 'customroutepost_callback_function',
    ]);
});

Vous aurez ainsi une nouvelle entrée dans vos routes REST, qui répondra aux appels POST /api/custom-route-post. C’est gagné !

Notez qu’au lieu de passer la méthode en texte (GET, POST etc.), il est préférable d’utiliser les constantes que propose la classe :

WP_REST_Server::READABLE // GET
WP_REST_Server::CREATABLE // POST
WP_REST_Server::EDITABLE // POST, PUT, PATCH
WP_REST_Server::DELETABLE // DELETE
WP_REST_Server::ALLMETHODS // GET, POST, PUT, PATCH, DELETE

 

Enfin, pour passer des paramètres aux routes GET, on peut suivre la documentation de la fonction register_rest_route, en les nommant dans la regex du endpoint pour les ensuite les retrouver dans l’objet WP_REST_Request du callback :

add_action('rest_api_init', function($server){
    $server->register_route('custom-route-get', '/custom-route-get/(?P<id>\d+)', [
        'methods'  => 'GET',
        'callback' => 'my_callback_action',
    ]);
});

function my_callback_action(WP_REST_Request $request){
    // Récupérer un paramètre en particulier :
    $id = $request->get_param('id');
    // Récupérer tous les paramètres : 
    $params = $request->get_params();

    return $id;
}

Pour les routes POST, les paramètres pourront être récupérés de la même manière dans la fonction de callback.