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 sishow_in_rest => true(Partie 7). Les réponses sont du JSON avec des champs commetitle.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êtesX-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
_fieldset_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). metan’apparaît que pour les clés enregistrées avecshow_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/_fieldspour 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éponseX-WP-Total(nombre total) etX-WP-TotalPagespermettent 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_pageplafonné à 100. On ne récupère pas 5 000 posts en une requête :per_pageest borné à 100. Pour tout parcourir, on pagine (boucle surpagejusqu’à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_metasansshow_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_restla 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 avecpermission_callback, ch. 9.3).
✏️ Exercices
- Quelle URL récupère les 5 derniers livres avec seulement
id,titleet le prix ? - Vous affichez une liste d’articles avec leur image et leur auteur. Comment éviter une requête par image ?
- Pourquoi votre CPT
evenementn’apparaît-il pas sous/wp-json/wp/v2/?
✅ Solution
/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).- Ajouter
_embed: la réponse inclut alors_embedded['wp:featuredmedia']et_embedded.author, évitant une requête par ressource liée (anti N+1). - 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).