register_rest_route() accepte un callback qui peut, en théorie, retourner à peu près n’importe quoi : un tableau associatif, un objet stdClass, un objet WP_Error, ou déjà un WP_REST_Response correctement construit. Le client qui consomme l’API, lui, attend un format cohérent et prévisible d’un endpoint à l’autre.
rest_ensure_response() fait le lien entre ces deux mondes : elle enveloppe systématiquement la valeur retournée dans un objet WP_REST_Response valide, sans dupliquer l’enveloppe si elle est déjà présente.
Ce que fait exactement la fonction
Si la valeur transmise est déjà une instance de WP_REST_Response, elle est retournée telle quelle. Si c’est une instance de WP_Error, elle est convertie en réponse d’erreur avec le bon code HTTP. Pour toute autre valeur — tableau, chaîne, objet simple — elle est enveloppée dans un nouveau WP_REST_Response avec un code 200 par défaut.

function mon_endpoint_callback( WP_REST_Request $request ) {
$donnees = array(
'statut' => 'ok',
'valeurs' => array( 1, 2, 3 ),
);
return rest_ensure_response( $donnees );
}
register_rest_route( 'mon-plugin/v1', '/donnees', array(
'methods' => 'GET',
'callback' => 'mon_endpoint_callback',
'permission_callback' => '__return_true',
) );
Pourquoi ne pas construire le WP_REST_Response à la main partout
Construire explicitement un new WP_REST_Response( $donnees, 200 ) à chaque retour fonctionne, mais ajoute une répétition dans chaque callback, surtout lorsque plusieurs chemins de retour existent dans une même fonction, certains renvoyant une erreur, d’autres un résultat valide.
function mon_endpoint_avec_erreur( WP_REST_Request $request ) {
$id = (int) $request->get_param( 'id' );
if ( $id <= 0 ) {
return rest_ensure_response(
new WP_Error( 'id_invalide', 'Identifiant invalide.', array( 'status' => 400 ) )
);
}
return rest_ensure_response( array( 'id' => $id ) );
}
Les deux branches passent par le même appel final, ce qui uniformise le style d’écriture du callback sans condition explicite sur le type de retour.
Ce que la fonction ne fait pas
- Elle ne valide pas la structure des données transmises : c’est le rôle de l’argument
argset de ses callbacks de validation dansregister_rest_route(). - Elle ne définit pas les en-têtes CORS ni la pagination : ces aspects se règlent séparément sur l’objet
WP_REST_Responseretourné, via ses méthodesset_headers()ouheader(). - Elle n’est pas obligatoire au sens strict : un endpoint peut fonctionner sans elle si chaque retour est déjà un
WP_REST_Responsebien formé, mais l’omettre revient à réécrire manuellement ce qu’elle fait déjà.
Un détail utile pour les erreurs multiples
Si un WP_Error contient plusieurs erreurs enregistrées via add_data(), rest_ensure_response() utilise le code de statut associé à la première erreur trouvée. Pour un contrôle plus précis du code HTTP retourné, un appel explicite à WP_Error::add_data() avec un tableau contenant la clé status reste nécessaire avant l’enveloppe.
Le réflexe à prendre en écrivant un callback REST : chaque instruction
returnpasse parrest_ensure_response(), sans exception, y compris pour les branches d’erreur. Cela évite un format de retour incohérent selon le chemin d’exécution emprunté.
En résumé
rest_ensure_response() uniformise le format de retour d’un callback d’endpoint REST, sans imposer de restructurer le code existant. Elle prend en charge aussi bien les valeurs simples que les objets WP_Error, et évite les conditions manuelles répétées à chaque point de sortie d’une fonction de callback.