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

SEO & GEO

Endpoint REST sur mesure : un flux structuré pour un agrégateur immobilier

Un snippet pour exposer des annonces au format Schema.org RealEstateListing via un point de terminaison REST personnalisé, destiné à un partenaire agrégateur.

Par Clément Hadrot • 23 mai 2024 • 4 min de lecture • Aucun commentaire
Endpoint REST sur mesure : un flux structuré pour un agrégateur immobilier

register_rest_route(). Cette fonction, disponible nativement depuis WordPress 4.4, suffit à construire un point de terminaison sur mesure sans dépendre d’une extension tierce, dès lors que le besoin sort du cadre standard de l’API REST fournie par défaut. C’est exactement le cas rencontré ici : un partenaire agrégateur immobilier demandait un flux structuré au format Schema.org RealEstateListing, un format que l’API REST native de WordPress, pensée pour exposer des articles bruts, ne produit pas telle quelle.

Ce billet ne traite pas la synchronisation bidirectionnelle avec le partenaire, uniquement l’exposition en lecture des annonces via ce point de terminaison, consommé côté agrégateur à intervalle régulier.

Pourquoi un endpoint dédié plutôt qu’un export générique

L’API REST native expose les annonces, enregistrées comme type de contenu personnalisé annonce_immo, sous une forme générique : titre, contenu, champs personnalisés bruts sans structure Schema.org. Transformer cette réponse générique au format attendu par le partenaire côté agrégateur aurait ajouté une couche de traitement chez un tiers qui ne maîtrise pas la structure interne du site. Il était plus robuste de produire directement, côté WordPress, une réponse déjà conforme au vocabulaire RealEstateListing.

Un endpoint dédié permet également de ne exposer que les champs nécessaires au partenaire, sans risque de fuite d’informations internes présentes dans les métadonnées brutes de l’annonce.

Le snippet : déclaration du point de terminaison

L'essentiel à retenir : Un point de terminaison REST dédié plutôt qu'un export générique ; Format RealEstateListing conforme aux attentes du partenaire ; Pagination et cache pensés pour un flux consommé régulièrement
add_action( 'rest_api_init', function () {
    register_rest_route( 'partenaire/v1', '/annonces', array(
        'methods'             => 'GET',
        'callback'            => 'partenaire_get_annonces',
        'permission_callback' => 'partenaire_verifier_cle_api',
        'args'                => array(
            'page' => array(
                'default'           => 1,
                'sanitize_callback' => 'absint',
            ),
        ),
    ) );
} );

La fonction partenaire_verifier_cle_api() contrôle une clé transmise en en-tête HTTP avant d’autoriser l’accès, une précaution nécessaire puisque ce flux, bien que public dans son principe, ne doit être consommé que par le partenaire identifié.

Construire la réponse au format RealEstateListing

function partenaire_get_annonces( WP_REST_Request $request ) {
    $page  = $request->get_param( 'page' );
    $query = new WP_Query( array(
        'post_type'      => 'annonce_immo',
        'post_status'    => 'publish',
        'posts_per_page' => 50,
        'paged'          => $page,
    ) );

    $annonces = array();
    foreach ( $query->posts as $post ) {
        $annonces[] = array(
            '@context'    => 'https://schema.org',
            '@type'       => 'RealEstateListing',
            'name'        => get_the_title( $post ),
            'url'         => get_permalink( $post ),
            'price'       => get_post_meta( $post->ID, 'prix', true ),
            'floorSize'   => get_post_meta( $post->ID, 'surface_m2', true ),
            'numberOfRooms' => get_post_meta( $post->ID, 'nb_pieces', true ),
            'address'     => get_post_meta( $post->ID, 'adresse', true ),
        );
    }

    return rest_ensure_response( array(
        'page'      => (int) $page,
        'totalPages'=> $query->max_num_pages,
        'annonces'  => $annonces,
    ) );
}

Chaque annonce est ainsi renvoyée avec la structure exacte attendue par le partenaire, en réutilisant le vocabulaire Schema.org déjà employé par ailleurs pour le balisage des pages d’annonces individuelles, ce qui garantit une cohérence entre ce que voit un moteur de recherche sur la page HTML et ce que consomme l’agrégateur via ce flux.

Pagination et cache : deux points souvent négligés

La pagination via paged et max_num_pages évite de renvoyer l’intégralité du catalogue en une seule réponse, un point critique dès que le nombre d’annonces dépasse quelques centaines. Côté cache, la réponse de cet endpoint est mise en cache via un transitoire WordPress d’une durée de quinze minutes, un compromis jugé raisonnable entre fraîcheur des données pour le partenaire et charge serveur, la fréquence de mise à jour des annonces ne justifiant pas un flux calculé à chaque requête.

  • Un transitoire par numéro de page, invalidé automatiquement à sa durée d’expiration.
  • Une invalidation manuelle possible via un hook déclenché à la publication d’une nouvelle annonce, pour les cas où la fraîcheur immédiate compte davantage.

En résumé

Construire un point de terminaison REST sur mesure avec register_rest_route() reste la solution la plus robuste dès qu’un partenaire exige un format structuré précis que l’API native ne produit pas nativement. Le travail principal ne réside pas dans la déclaration de la route elle-même, mais dans la construction fidèle du vocabulaire Schema.org attendu et dans une gestion de pagination et de cache adaptée à la volumétrie réelle du catalogue.

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