Skip to Content

Chapitre 9.1 — La REST API interne

⏱️ TL;DR — WordPress expose nativement une REST API sous /wp-json/. Les routes standard vivent sous /wp-json/wp/v2/ : posts, pages, media, users, categories, tags, et vos CPT/taxonomies si show_in_rest => true (Partie 7). Les réponses sont du JSON avec des champs comme title.rendered, content.rendered, meta. On optimise avec _fields (limiter les champs), _embed (inclure les ressources liées), et la pagination (per_page, page, en-têtes X-WP-Total). C’est la fondation du headless.

🎯 Objectifs

  • Explorer les routes natives et la structure des réponses.
  • Filtrer, paginer, trier via les paramètres de requête.
  • Optimiser avec _fields et _embed.
  • Comprendre ce qui est exposé (et ce qui ne l’est pas).

1. Le point d’entrée : /wp-json/

Toute installation expose l’API sous /wp-json/. L’index liste les routes disponibles :

GET https://monsite.com/wp-json/ → l'index (namespaces, routes) GET https://monsite.com/wp-json/wp/v2/posts → les articles publiés GET https://monsite.com/wp-json/wp/v2/livre → vos livres (si show_in_rest)

Le namespace du cœur est wp/v2. Les plugins ajoutent leurs propres namespaces (woocommerce/v3, wpr-books/v1, ch. 9.3).

⚠️ Piège — permalinks « simples ». Les jolies routes /wp-json/… nécessitent une structure de permaliens activée (ch. 2.1). En permaliens « simples » (?p=123), l’API répond via ?rest_route=/wp/v2/posts. Activez une vraie structure de permaliens pour des routes propres.


2. La structure d’une réponse

// GET /wp-json/wp/v2/posts/42 { "id": 42, "date": "2026-07-08T10:00:00", "slug": "mon-article", "status": "publish", "title": { "rendered": "Mon article" }, "content": { "rendered": "<p>…HTML…</p>", "protected": false }, "excerpt": { "rendered": "<p>Résumé…</p>" }, "author": 1, "featured_media": 99, "categories": [ 5, 8 ], "meta": { "wpr_isbn": "978-…" }, "_links": { "self": [ ], "author": [ ], "wp:featuredmedia": [ ] } }
  • Les champs texte sont des objets { rendered: … } (HTML déjà rendu par WordPress, filtres appliqués).
  • meta n’apparaît que pour les clés enregistrées avec show_in_rest (ch. 7.4).
  • _links (HAL) pointe vers les ressources liées (auteur, média…) — exploitables via _embed.

💡 Pour un dev React — La REST API de WordPress est une API REST classique : ressources, verbes HTTP (GET/POST/PUT/DELETE), pagination, filtres en query string. title.rendered = le HTML prêt à afficher ; title.raw (avec auth + context=edit) = la source. Vous consommez ça comme n’importe quelle API — la seule spécificité est la forme { rendered } et le système _embed/_fields pour optimiser le payload.


3. Filtrer, trier, paginer

Les paramètres de requête standard :

/wp/v2/posts?per_page=10&page=2 → pagination /wp/v2/posts?search=react → recherche /wp/v2/posts?categories=5&orderby=date&order=desc /wp/v2/livre?genre=3 → CPT filtré par taxonomie (si exposée) /wp/v2/posts?status=draft → nécessite une authentification
  • Pagination : per_page (max 100), page. Les en-têtes de réponse X-WP-Total (nombre total) et X-WP-TotalPages permettent d’afficher une pagination.
  • Tri : orderby (date, title, menu_order…), order.
  • Filtres : par taxonomie, auteur, statut (auth requise pour non-publiés), dates.

⚠️ Piège — per_page plafonné à 100. On ne récupère pas 5 000 posts en une requête : per_page est borné à 100. Pour tout parcourir, on pagine (boucle sur page jusqu’à X-WP-TotalPages). En headless (ch. 9.5), on génère souvent les pages par lots + ISR plutôt que tout charger d’un coup.


4. Optimiser le payload : _fields et _embed

_fields — ne demander que les champs utiles (réduit la taille et le temps) :

/wp/v2/livre?_fields=id,title,slug,meta.wpr_prix

_embed — inclure les ressources liées (auteur, image mise en avant, termes) en une requête, au lieu d’en refaire une par lien :

/wp/v2/posts?_embed → la réponse contient _embedded.author, _embedded['wp:featuredmedia'], etc.

_embed évite le N+1 (une requête image par article). Combinez _fields + _embed pour des réponses maigres et complètes.


5. Ce qui est exposé (et pas)

  • Exposé : contenus publiés des types show_in_rest, taxonomies exposées, médias, users (partiellement), meta enregistrées.
  • Non exposé par défaut : les brouillons (auth requise), les meta non enregistrées (register_post_meta sans show_in_rest), les données privées.
  • Attention : l’API expose par défaut la liste des utilisateurs (/wp/v2/users) et l’auteur des posts — à considérer côté vie privée/sécurité (on peut restreindre, ch. 9.2 & Partie 11).

⚠️ Piège — exposer trop. Rendre une meta show_in_rest la publie à tous (endpoint public). N’exposez pas de données internes/sensibles sans réfléchir. Pour du privé, contrôlez l’accès (auth_callback, endpoints custom avec permission_callback, ch. 9.3).


✏️ Exercices

  1. Quelle URL récupère les 5 derniers livres avec seulement id, title et le prix ?
  2. Vous affichez une liste d’articles avec leur image et leur auteur. Comment éviter une requête par image ?
  3. Pourquoi votre CPT evenement n’apparaît-il pas sous /wp-json/wp/v2/ ?

✅ Solution

  1. /wp-json/wp/v2/livre?per_page=5&orderby=date&order=desc&_fields=id,title,meta.wpr_prix (le prix suppose la meta exposée en REST).
  2. Ajouter _embed : la réponse inclut alors _embedded['wp:featuredmedia'] et _embedded.author, évitant une requête par ressource liée (anti N+1).
  3. Il manque show_in_rest => true à l’enregistrement du CPT (ch. 7.3) : sans elle, le type n’est pas exposé dans la REST API.

🧠 Quiz de révision

1. Sous quel préfixe vit la REST API ?

/wp-json/ (routes du cœur sous /wp-json/wp/v2/).

2. Sous quelle forme sont les champs texte ?

Des objets { "rendered": "…" } (HTML rendu ; raw avec auth + context=edit).

3. À quoi sert _embed ?

À inclure les ressources liées (auteur, image, termes) en une requête (évite le N+1).

4. Quelle est la limite de per_page ?

100 ; au-delà, il faut paginer (page, en-têtes X-WP-TotalPages).

5. Comment exposer une meta dans l’API ?

L’enregistrer avec register_post_meta(..., 'show_in_rest' => true) (Partie 7).


Chapitre suivant : Authentification (tokens, nonces).