Un client avait un formulaire d’import qui créait à la fois un article, deux termes de taxonomie associés et une pièce jointe de couverture, depuis un front découplé. Sans mécanisme de regroupement, cela signifiait quatre requêtes HTTP successives, quatre montées TLS, et une gestion d’erreur partielle délicate : que faire si la troisième requête échoue après que les deux premières ont réussi ?
WordPress 5.6 a introduit une réponse à ce problème précis : l’endpoint /batch/v1, qui accepte plusieurs sous-requêtes dans un seul appel HTTP.
La forme d’une requête groupée
L’appel se fait en POST vers /wp-json/batch/v1, avec un tableau de requêtes décrites chacune par leur méthode, leur chemin et leur corps :
POST /wp-json/batch/v1
{
"requests": [
{ "method": "POST", "path": "/wp/v2/posts", "body": { "title": "Nouvel article", "status": "draft" } },
{ "method": "POST", "path": "/wp/v2/tags", "body": { "name": "Voyage" } },
{ "method": "POST", "path": "/wp/v2/tags", "body": { "name": "Reportage" } }
]
}
Chaque sous-requête est authentifiée exactement comme si elle était envoyée seule : les mêmes vérifications de permissions s’appliquent, requête par requête.
Une exécution individuelle, pas transactionnelle
Il faut bien comprendre ce que le batch ne fait pas : il n’offre aucune garantie transactionnelle. Si la deuxième sous-requête échoue, la première reste appliquée. La réponse renvoie un tableau de résultats dans le même ordre que les requêtes envoyées, chacun avec son propre code de statut, à vérifier individuellement plutôt que de se fier à un code de statut global.

Lire la réponse correctement
{
"responses": [
{ "status": 201, "body": { "id": 4821, "title": { "raw": "Nouvel article" } } },
{ "status": 201, "body": { "id": 57, "name": "Voyage" } },
{ "status": 400, "body": { "code": "term_exists" } }
]
}
Sur ce projet, on a dû boucler sur ce tableau de réponses pour associer chaque résultat à sa sous-requête d’origine et gérer l’échec du troisième appel sans annuler les deux premiers, en proposant à l’utilisateur de relancer uniquement la partie qui a échoué.
La limite de taille du lot
Par défaut, un lot ne peut pas dépasser 25 sous-requêtes, une valeur exposée par le filtre rest_get_max_batch_size côté PHP si un projet a réellement besoin de l’ajuster. Dépasser cette limite renvoie une erreur immédiate sans exécuter la moindre sous-requête, ce qui évite au moins les exécutions partielles imprévues sur un lot trop volumineux.
Un piège avec les dépendances entre sous-requêtes
Une limite moins documentée : une sous-requête du lot ne peut pas référencer directement l’identifiant créé par une sous-requête précédente du même lot. Sur ce projet, l’article et ses termes de taxonomie ont donc été créés en parallèle dans le même lot, puis une seconde requête, hors du batch, a associé l’identifiant de l’article fraîchement créé aux identifiants de termes également fraîchement créés. Le batch réduit les allers-retours pour des écritures indépendantes entre elles, pas pour une chaîne de créations qui dépendent les unes des autres.
Ce que l’endpoint batch ne remplace pas
- Une vraie logique métier transactionnelle, à garder côté serveur si l’atomicité est requise (par exemple via un point de terminaison personnalisé qui encapsule la logique entière).
- Un import massif de plusieurs milliers d’éléments, pour lequel une tâche en arrière-plan reste plus adaptée qu’un appel HTTP synchrone.
Le batch REST est un bon outil pour réduire la latence perçue d’un formulaire qui écrit à plusieurs endroits à la fois, pas un substitut à une vraie transaction métier côté serveur.
Ce qu’on retient
L’endpoint /batch/v1 réduit efficacement le nombre d’allers-retours réseau pour des écritures liées entre elles, à condition d’accepter son fonctionnement non transactionnel et de traiter chaque réponse individuellement. Pour ce formulaire d’import, le temps de soumission perçu est passé de quatre requêtes séquentielles à une seule, avec une gestion d’erreur plus fine qu’avant, sous-requête par sous-requête.