Magento 2 REST API : Guide des bonnes pratiques (2026)
L’API REST de Magento 2 est le pilier des intégrations tierces — synchronisations ERP, connexions CRM, applications mobiles et vitrines headless. Adobe continue d’investir dans REST aux côtés de GraphQL, et REST reste le protocole recommandé pour les intégrations au niveau admin et les opérations groupées. Ce guide des bonnes pratiques couvre la conception d’endpoints, l’authentification, la gestion des erreurs, la mise en cache et les modèles de production pour construire des API REST Magento 2 fiables en 2026.
En résumé : L’API REST expose des ressources sous
/rest/V1/avec les verbes CRUD standards. Utilisez l’authentification par token pour les intégrations, OAuth 1.0 pour les applications tierces, et incluez toujours des réponses d’erreur appropriées, la pagination et les en-têtes de cache. Pour les interactions côté vitrine, consultez le guide GraphQL dédié .
Table des matières
- REST vs GraphQL : lequel utiliser
- Méthodes d’authentification
- Structure des endpoints et conventions de nommage
- Formats des requêtes et réponses
- Gestion des erreurs et codes de réponse
- Pagination et filtrage
- Opérations groupées et API asynchrones
- Mise en cache et en-têtes ETag
- Création d’endpoints REST personnalisés
- Modèles d’intégration pour ERP/CRM
- Tests et documentation
- FAQ
REST vs GraphQL : lequel utiliser
Magento 2 prend en charge les API REST et GraphQL. Chacune a ses points forts :
| Scénario | Recommandation |
|---|---|
| Intégrations admin (ERP, CRM, OMS) | REST — couverture plus large des opérations admin |
| Vitrine/application mobile | GraphQL — moins de requêtes, schéma typé |
| Synchronisation de données groupée | REST — endpoints bulk et asynchrones |
| Checkout en temps réel | GraphQL — une seule mutation pour tout le checkout |
| Accès application tierce | REST — support OAuth 1.0 |
Pour une couverture détaillée de GraphQL, consultez la documentation GraphQL . Ce guide se concentre sur le développement et l’intégration REST.
Méthodes d’authentification
Tokens d’intégration (recommandé pour serveur à serveur)
Créez une intégration dans Stores → Configuration → Integrations dans le panneau d’administration. Cela génère un token d’accès avec des permissions spécifiques sur les ressources :
# Demander un token
curl -X POST https://store.com/rest/V1/integration/admin/token \
-H "Content-Type: application/json" \
-d '{"username": "integration_name", "password": "integration_password"}'
# Réponse : "q7x3p2m9..."
# Utiliser le token dans les requêtes suivantes
curl https://store.com/rest/V1/products/24-MB01 \
-H "Authorization: Bearer q7x3p2m9..."
Les tokens d’intégration sont persistants et limités aux ressources API de l’intégration. Faites-les pivoter périodiquement via le panneau d’administration.
Token admin (à utiliser avec prudence)
curl -X POST https://store.com/rest/V1/integration/admin/token \
-H "Content-Type: application/json" \
-d '{"username": "admin_user", "password": "admin_password"}'
Les tokens admin sont liés à un compte utilisateur admin. Lorsque l’admin change son mot de passe, tous les tokens existants sont invalidés. Préférez les tokens d’intégration pour les intégrations automatisées.
Tokens client
curl -X POST https://store.com/rest/V1/integration/customer/token \
-H "Content-Type: application/json" \
-d '{"username": "[email protected]", "password": "customer_password"}'
Les tokens client sont utilisés pour les intégrations côté vitrine (applications mobiles, frontends personnalisés). Ils ont uniquement les permissions au niveau client.
OAuth 1.0
Pour les applications tierces nécessitant un accès délégué, Magento prend en charge OAuth 1.0 avec oauth_token et oauth_token_secret. C’est plus complexe mais permet un périmètre de permissions fin sans partager les identifiants admin.
Structure des endpoints et conventions de nommage
L’API REST de Magento 2 suit un modèle d’URL cohérent :
/rest/V1/{resource}/[id]/[subresource]/[subresource_id]
Ressources intégrées
| Endpoint | Objectif |
|---|---|
GET /rest/V1/products/:sku | Obtenir un produit par SKU |
POST /rest/V1/products | Créer un produit |
PUT /rest/V1/products/:sku | Mettre à jour un produit |
DELETE /rest/V1/products/:sku | Supprimer un produit |
GET /rest/V1/customers/:id | Obtenir un client |
GET /rest/V1/orders/:id | Obtenir une commande |
POST /rest/V1/cart/mine/order | Passer une commande (panier client) |
GET /rest/V1/categories/:id | Obtenir une catégorie |
Endpoints de recherche
La plupart des ressources prennent en charge la recherche via GET /rest/V1/{resource}/search :
GET /rest/V1/products/search?
searchCriteria[filterGroups][0][filters][0][field]=sku&
searchCriteria[filterGroups][0][filters][0][value]=24-MB&
searchCriteria[filterGroups][0][filters][0][conditionType]=like&
searchCriteria[pageSize]=20&
searchCriteria[currentPage]=1
La réponse inclut le nombre total et les éléments. Implémentez toujours la pagination — ne demandez jamais tous les enregistrements à la fois.
Formats des requêtes et réponses
Toutes les requêtes et réponses utilisent application/json. Suivez les structures standards de Magento :
Requête :
{
"product": {
"sku": "CUSTOM-SKU-001",
"name": "Custom Product",
"price": 29.99,
"status": 1,
"visibility": 4,
"type_id": "simple",
"attribute_set_id": 4,
"extension_attributes": {
"stock_item": {
"qty": 100,
"is_in_stock": true
}
},
"custom_attributes": [
{
"attribute_code": "description",
"value": "Product description here"
}
]
}
}
Réponse réussie (200/201) :
{
"id": 42,
"sku": "CUSTOM-SKU-001",
"name": "Custom Product",
...
}
Gestion des erreurs et codes de réponse
Une API bien conçue renvoie des codes HTTP appropriés et des corps d’erreur structurés.
Codes HTTP standards
| Code | Signification | Quand l’utiliser |
|---|---|---|
200 | OK | GET, PUT, DELETE réussis |
201 | Created | POST réussi (ressource créée) |
400 | Bad Request | JSON mal formé ou erreurs de validation |
401 | Unauthorized | Authentification manquante ou invalide |
403 | Forbidden | Authentifié mais non autorisé |
404 | Not Found | La ressource n’existe pas |
422 | Unprocessable Entity | Échec de validation de la logique métier |
429 | Too Many Requests | Limitation de débit |
500 | Internal Server Error | Erreur serveur inattendue |
Structure des réponses d’erreur
Format d’erreur standard de Magento :
{
"message": "Product with SKU \"CUSTOM-SKU-001\" already exists.",
"trace": "...",
"parameters": {
"sku": "CUSTOM-SKU-001"
}
}
Pour les endpoints personnalisés, renvoyez des erreurs structurées de manière cohérente :
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Webapi\Exception as WebapiException;
// Erreur de validation
throw new WebapiException(
__('Product SKU is required'),
0,
WebapiException::HTTP_BAD_REQUEST
);
// Ressource non trouvée
throw new LocalizedException(
__('Product with SKU "%1" not found.', $sku)
);
Pagination et filtrage
Paginez toujours les endpoints de collection. Utilisez les modèles searchCriteria de Magento de manière cohérente :
GET /rest/V1/products/search?
searchCriteria[filterGroups][0][filters][0][field]=price&
searchCriteria[filterGroups][0][filters][0][value]=50&
searchCriteria[filterGroups][0][filters][0][conditionType]=gteq&
searchCriteria[sortOrders][0][field]=created_at&
searchCriteria[sortOrders][0][direction]=DESC&
searchCriteria[pageSize]=50&
searchCriteria[currentPage]=2
La réponse inclut le nombre total pour l’interface de pagination côté client :
{
"total_count": 342,
"items": [ ... ]
}
Opérations groupées et API asynchrones
Pour les synchronisations de données volumineuses, utilisez les endpoints d’API groupée de Magento :
# Création groupée asynchrone de produits
POST /rest/V1/async/bulk/V1/products
Content-Type: application/json
Authorization: Bearer {token}
[
{ "product": { "sku": "BULK-001", "name": "Bulk 1", "price": 10 } },
{ "product": { "sku": "BULK-002", "name": "Bulk 2", "price": 20 } },
...
]
L’endpoint asynchrone renvoie immédiatement un UUID groupé et traite les opérations en arrière-plan via les files d’attente. Interrogez le statut via :
GET /rest/V1/bulk/{bulkUuid}/status
Les opérations groupées sont essentielles pour les intégrations ERP/CRM qui synchronisent des milliers de produits, clients ou commandes. Elles évitent les timeouts d’API et réduisent la charge serveur.
Mise en cache et en-têtes ETag
L’API REST respecte la mise en cache HTTP standard. Pour les endpoints de lecture qui renvoient des données changeant rarement (catégories, blocs CMS, configuration boutique), incluez des en-têtes de cache :
// Dans votre endpoint personnalisé
$this->resultFactory->create(ResultFactory::TYPE_JSON)
->setData($data)
->setHeader('Cache-Control', 'public, max-age=3600')
->setHeader('ETag', md5(serialize($data)));
Les clients peuvent ensuite envoyer des en-têtes If-None-Match pour recevoir des réponses 304 Not Modified lorsque les données n’ont pas changé — économisant de la bande passante et du temps de traitement.
Création d’endpoints REST personnalisés
1. Définir les routes dans webapi.xml
<!-- app/code/Vendor/Module/etc/webapi.xml -->
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route url="/V1/vendor/price-check/:sku" method="GET">
<service class="Vendor\Module\Api\PriceManagementInterface" method="getPrice"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>
La section resources définit les permissions. Utilisez anonymous pour les endpoints publics, ou référencez des ressources ACL spécifiques pour les endpoints réservés à l’admin.
2. Créer l’interface de service
<?php
declare(strict_types=1);
namespace Vendor\Module\Api;
interface PriceManagementInterface
{
/**
* Get current price and special price for a product
*
* @param string $sku
* @return \Vendor\Module\Api\Data\PriceDataInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getPrice(string $sku): \Vendor\Module\Api\Data\PriceDataInterface;
}
3. Créer l’interface de données
<?php
declare(strict_types=1);
namespace Vendor\Module\Api\Data;
interface PriceDataInterface
{
/**
* @return float
*/
public function getPrice(): float;
/**
* @param float $price
* @return $this
*/
public function setPrice(float $price): self;
/**
* @return float|null
*/
public function getSpecialPrice(): ?float;
/**
* @param float|null $specialPrice
* @return $this
*/
public function setSpecialPrice(?float $specialPrice): self;
}
4. Implémenter le service
<?php
declare(strict_types=1);
namespace Vendor\Module\Model;
use Vendor\Module\Api\PriceManagementInterface;
use Vendor\Module\Api\Data\PriceDataInterfaceFactory;
use Magento\Catalog\Api\ProductRepositoryInterface;
class PriceManagement implements PriceManagementInterface
{
public function __construct(
private readonly ProductRepositoryInterface $productRepository,
private readonly PriceDataInterfaceFactory $priceDataFactory
) {}
public function getPrice(string $sku): PriceDataInterface
{
$product = $this->productRepository->get($sku);
$priceData = $this->priceDataFactory->create();
$priceData->setPrice((float)$product->getPrice());
$priceData->setSpecialPrice($product->getSpecialPrice() !== null
? (float)$product->getSpecialPrice()
: null);
return $priceData;
}
}
5. Ajouter des extension_attributes pour l’extensibilité
<!-- app/code/Vendor/Module/etc/extension_attributes.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
<attribute code="custom_badge" type="string"/>
</extension_attributes>
</config>
Modèles d’intégration pour ERP/CRM
Synchronisation des commandes (Magento → ERP)
Utilisez l’
observer
sales_order_save_after de Magento pour mettre en file d’attente les données de commande à exporter. Traitez via cron job ou file de messages :
Commande passée → Observer déclenché → Données de commande mises en file d'attente
↓
Le cron récupère la file
↓
POST vers l'endpoint ERP
↓
Marquer la commande comme exportée
Synchronisation des stocks (ERP → Magento)
Utilisez l’API REST groupée pour les mises à jour de stock :
POST /rest/V1/async/bulk/V1/products/bySkus/stockItems
[
{ "sku": "PROD-001", "qty": 50, "is_in_stock": true },
{ "sku": "PROD-002", "qty": 0, "is_in_stock": false }
]
Exécutez ceci comme une tâche planifiée côté ERP toutes les 5 à 15 minutes selon la volatilité des stocks.
Envoi de clients (CRM → Magento)
POST /rest/V1/async/bulk/V1/customers
[
{
"customer": {
"email": "[email protected]",
"firstname": "John",
"lastname": "Doe",
"website_id": 1,
"store_id": 1,
"group_id": 1
},
"password": "temporary_password"
}
]
Envoyez les e-mails de bienvenue depuis Magento (jamais depuis le système externe) pour maintenir une image de marque et une délivrabilité cohérentes.
Tests et documentation
Tests avec une collection Postman
Exportez vos endpoints API Magento 2 sous forme de collection Postman. Incluez :
- Variables d’environnement pour l’URL de base, le token
- Scripts pré-requête pour la génération de token
- Exemples de corps pour chaque endpoint
- Scripts de test validant la structure des réponses
Tests API automatisés
# Utilisez le framework de test d'intégration de Magento
vendor/bin/phpunit -c dev/tests/integration/phpunit.xml \
--filter testPriceEndpoint
Documentation OpenAPI/Swagger
Magento 2 génère la documentation Swagger à /rest/V1/swagger en mode développeur. Pour les endpoints personnalisés, annotez les interfaces avec des tags OpenAPI :
/**
* Get product price
*
* @api
* @param string $sku
* @return PriceDataInterface
* @throws NoSuchEntityException
*/
public function getPrice(string $sku): PriceDataInterface;
FAQ
Q : Quelle est la différence entre REST et GraphQL dans Magento 2 ?
REST suit des modèles d’URL basés sur les ressources et est meilleur pour les intégrations admin. GraphQL est basé sur les requêtes et meilleur pour les vitrines/applications mobiles. Consultez le guide de comparaison GraphQL
pour les détails.
Q : Comment gérer la limitation de débit pour l’API REST ?
Magento 2 n’a pas de limitation de débit intégrée. Implémentez-la au niveau du serveur web (Nginx limit_req_zone) ou utilisez un CDN prenant en charge la limitation de débit.
Q : Puis-je utiliser l’API REST pour le checkout ?
Oui, mais GraphQL est préféré pour le checkout côté vitrine car il réduit le nombre de requêtes. Le checkout REST nécessite plusieurs appels (ajout au panier, définition de l’expédition, définition du paiement, passage de la commande).
Q : Comment sécuriser les endpoints API pour un accès public ?
Utilisez resource ref="anonymous" dans webapi.xml pour les endpoints publics. Pour les endpoints nécessitant une validation sans authentification complète, implémentez une vérification HMAC personnalisée ou une validation d’en-tête de clé API dans un plugin.
Q : Taille maximale des requêtes API groupées ?
Cela dépend de votre configuration PHP (upload_max_filesize, post_max_size) et des limites du serveur web. Pour les très grandes charges utiles (10 000+ éléments), divisez en lots de 100 à 500 et utilisez l’API asynchrone groupée.
Q : Comment tester les endpoints personnalisés localement ?
Utilisez CURL, Postman ou Insomnia. Définissez app/etc/env.php MAGE_MODE sur developer pour voir les messages d’erreur détaillés. Magento fournit également des suites de tests d’intégration pour les tests API.
Besoin d’une intégration API personnalisée pour votre boutique Magento 2 ? Consultez mon service API & intégrations et mon service de modules personnalisés . Voir aussi le guide GraphQL vitrine pour les modèles d’API côté vitrine.