Conseils sur la limitation des API pour les partenaires appelant les API du Centre des partenaires
Microsoft implémente la limitation des API pour permettre des performances plus cohérentes dans un intervalle de temps pour les partenaires appelant les API de l’Espace partenaires. La limitation restreint le nombre de requêtes pouvant être adressées à un service dans un laps de temps donné pour empêcher une surutilisation de ressources. Bien que l’Espace partenaires soit conçu pour gérer un gros volume de requêtes, si un petit nombre de partenaires exécute un nombre excessif de requêtes, la limitation permet de maintenir un niveau de performance et une fiabilité optimum pour tous les partenaires.
Les limites varient selon les scénarios. Par exemple, si vous effectuez un grand volume d’écritures, la possibilité de limitation est plus élevée que si vous effectuez uniquement des lectures.
Que se passe-t-il lorsque la limitation se produit ?
Quand un seuil de limitation est dépassé, l’Espace partenaires limite les requêtes supplémentaires en provenance du client pendant un certain temps. Le comportement de limitation dépend du type et du nombre de requêtes.
Scénarios de limitation courants
Les causes les plus courantes de la limitation des clients sont les suivantes :
- Un grand nombre de demandes d’API par ID de locataire partenaire : pour certaines API de l’Espace partenaires, la limitation est déterminée par l’ID de locataire partenaire. Trop d’appels à ces API sur le même ID de locataire partenaire entraînent un dépassement du seuil de limitation.
- Un grand nombre de demandes d’API par ID de locataire partenaire par ID de locataire client : pour d’autres API, la limitation est déterminée par l’ID de locataire partenaire/ID de locataire client ; dans ce cas, l’exécution d’un trop grand nombre d’appels sur le même ID client entraîne une limitation, tandis que les appels contre d’autres clients peuvent réussir.
Bonnes pratiques de gestion de la limitation
Les pratiques de programmation, telles que l’interrogation continue d’une ressource pour rechercher les mises à jour et l’analyse régulière des collections de ressources afin de rechercher des ressources nouvelles ou supprimées, sont plus susceptibles d’entraîner une limitation et une dégradation des performances globales. Les appels d’API simultanés peuvent entraîner un nombre élevé de requêtes par heure unitaire, ce qui entraîne la limitation des requêtes. Vous devez utiliser plutôt le suivi des modifications et les notifications de modification. En outre, vous devez être en mesure d’utiliser les journaux d’activité pour détecter les modifications. Pour plus d’informations, consultez les journaux d’activité de l’Espace partenaires. Nous recommandons vivement aux partenaires d’utiliser l’API du journal d’activité pour plus d’efficacité et d’éviter la limitation. Consultez également l’exemple d’utilisation des journaux d’activité, ci-dessous.
Bonnes pratiques de gestion de la limitation
Voici les meilleures pratiques pour gérer la limitation :
- Réduisez le degré de parallélisme.
- Réduisez la fréquence des appels.
- Évitez les nouvelles tentatives immédiates car toutes les requêtes exécutées sont comptées dans vos limites d’utilisation.
Lorsque vous implémentez la gestion des erreurs, utilisez le code d’erreur HTTP 429 pour détecter la limitation. La réponse ayant échoué comprend l’en-tête de réponse Retry-After. La méthode la plus rapide pour effectuer une récupération suite à une limitation consiste à reporter les requêtes à l’aide du délai Retry-After.
Pour utiliser le délai de nouvelle tentative :
- Attendez le nombre de secondes spécifiées dans l’en-tête Retry-After.
- Relancez la requête.
- Si la demande échoue à nouveau avec un code d’erreur 429, vous êtes toujours limité. Réessayez avec le backoff exponentiel, utilisez le délai Retry-After recommandé et réessayez la demande jusqu’à ce qu’elle réussisse.
- Si vous utilisez le Kit de développement logiciel (SDK), vous recevez une exception avec le code d’état 429 lorsque votre demande est limitée. Utilisez la propriété RetryAfter dans l’exception et réessayez la demande une fois le temps écoulé.
API actuellement affectées par la limitation
À la fin, chaque API de l’Espace partenaires qui appelle le point de terminaison « api.partnercenter.microsoft.com/ » est limitée. Actuellement, les limites de limitation sont appliquées uniquement aux API répertoriées ci-dessous. L’Espace partenaires collecte les données de télémétrie sur chacune des API et ajuste dynamiquement les limites de limitation. Le tableau suivant répertorie les API où la limitation est actuellement appliquée.
Opération | Documentation sur l'Espace partenaires |
---|---|
{baseURL}/v1/customers/{customer_id}/orders | créer une commande |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription}/upgrades | transition d’un abonnement |
{baseURL}/v1/customers/{customer-tenant-id}/orders/{order-id} | acheter un module complémentaire à un abonnement |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | créer un panier |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id}/checkout | caisse d’un panier |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | mettre à jour un panier |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/registrations | inscrire un abonnement |
{baseURL}/v1/productupgrades | créer une entité de mise à niveau de produit |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | convertir un abonnement d’essai en abonnement payant |
{baseURL}/v1/customers/{customer-tenant-id} | obtenir un client par ID |
{baseURL}/v1/customers ?size={size} | obtenir la liste des clients |
{baseURL}/v1/productUpgrades/éligibilité | obtenir l’éligibilité pour la mise à niveau du produit |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription} | gérer l’abonnement |
{baseURL}/v1/customers/{customer_id}/subscriptions | get-all-of-a-customer-s-subscriptions |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Obtenir un abonnement par ID |
{baseURL}/v1/customers/{customer_id}/orders | Obtenir toutes les commandes client |
{baseURL}/v1/customers/{customer_id}/orders/{order_id} | Obtenir une commande par ID |
{baseURL}/v1/customers/{customer_id}/orders/{order_id}/provisioningstatus | Obtenir l’état de provisionnement d’un abonnement |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Gérer les commandes et gérer un abonnement |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/addons | Obtenir la liste des extensions d’un abonnement |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/azureEntitlements | Obtenir la liste des droits Azure d’un abonnement |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/registrationstatus | Obtenir l’état d’inscription d’un abonnement |
{baseURL}/v1/customers/{customer-tenant-id}/transfers | Obtenir tous les transferts d’un client |
{baseURL}/v1/productUpgrades/{upgrade-id}/status | Obtenir l’état de mise à niveau du produit |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | Obtenir la liste des offres de conversion d’essai |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce/validate | Valider un abonnement pour la migration |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce | Créer une migration commerciale |
{baseURL}/v1/customers/{customerId}/promotionEligibilities | Vérifier l’éligibilité d’une promotion |
Réponse du code d’erreur :
HTTP/1.1 429 Too Many Requests
Content-Length: 84
Content-Type: application/json
Retry-After: 57
Date: Tue, 21 Jul 2020 04:10:58 GMT
{ "statusCode": 429, "message": "Rate limit is exceeded. Try again in 57 seconds." }
Exemple de journal d’activité
Pour une bonne pratique d’analyse des modifications quotidiennes, nous vous recommandons d’interroger l’enregistrement d’audit pour une journée spécifique.
Dans la réponse, vous obtenez un résultat avec des modifications apportées au type d’opération spécifique. Vous pouvez filtrer en fonction de l’opération à laquelle vous vous intéressez. Par exemple, si vous êtes intéressé par un client nouvellement créé, vous pouvez examiner operationType = « add_customer ».
Vous trouverez la liste des opérations/ressources dans ces documents d’API.
Exemple de réponse
Demande :
Http Get call: https://api.partnercenter.microsoft.com/v1/auditrecords?startDate=2020-09-02&endDate=2020-09-02&size=50
Authorization: Bearer <token>
Accept: application/json
MS-RequestId: 127facaa-e389-41f8-8bb7-1d1af99db893
MS-CorrelationId: aaaa0000-bb11-2222-33cc-444444dddddd
X-Locale: en-US
Host: api.partnercenter.microsoft.com
Connection: Keep-Alive
Réponse :
{
"totalCount": 17,
"items": [
{
"id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_e905b566-4779-4e57-944c-7b1b5312705b_updatecustomeruserlicenses_637346859797753934",
"partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d",
"participants": [
"9daaeb1c-4195-4db5-9f1d-509eb70c8c2d"
],
"customerId": "e905b566-4779-4e57-944c-7b1b5312705b",
"userPrincipalName": "admin@testsw09.onmicrosoft.com",
"applicationId": "FulfillmentService",
"resourceType": "license",
"operationType": "update_customer_user_licenses",
"operationDate": "2020-09-02T23:26:19.7753934Z",
"operationStatus": "succeeded",
"customizedData": [
{
"key": "CustomerUserId",
"value": "933808c7-b165-496c-a24e-1a4b7846fab4"
}
],
"attributes": {
"objectType": "AuditRecord"
}
},
{
"id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_86bddccf-9a53-40c6-907c-08067a3f8da7_ia80zlkxp6ewoqpp35pbqjlhqv9iigvz1_createorder_637346662909268372",
"partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d",
"participants": [
"9daaeb1c-4195-4db5-9f1d-509eb70c8c2d"
],
"customerId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
"customerName": "CustomMetersStagingTest",
"userPrincipalName": "admin@testsw09.onmicrosoft.com",
"applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"resourceType": "order",
"resourceNewValue": "{\"Id\":\"Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"AlternateId\":\"64144d300bde\",\"ReferenceCustomerId\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"BillingCycle\":\"monthly\",\"CurrencyCode\":\"USD\",\"CurrencySymbol\":\"$\",\"LineItems\":[{\"LineItemNumber\":0,\"ProvisioningContext\":null,\"OfferId\":\"DZH318Z0C964:0001:DZH318Z0BZDG\",\"SubscriptionId\":\"aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e\",\"ParentSubscriptionId\":null,\"TermDuration\":\"P1M\",\"TransactionType\":\"New\",\"FriendlyName\":\"SaaS custom meter offer - Bronze\",\"Quantity\":1,\"Pricing\":null,\"PartnerIdOnRecord\":null,\"RenewsTo\":null,\"Links\":{\"Product\":{\"Uri\":\"/products/DZH318Z0C964?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"Sku\":{\"Uri\":\"/products/DZH318Z0C964/skus/0001?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"Availability\":{\"Uri\":\"/products/DZH318Z0C964/skus/0001/availabilities/DZH318Z0BZDG?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"ActivationLinks\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1/lineitems/0/activationlinks\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]}}}],\"CreationDate\":\"2020-09-02T17:58:01.7755853Z\",\"Status\":\"pending\",\"TransactionType\":\"UserPurchase\",\"Links\":{\"Self\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"ProvisioningStatus\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1/provisioningstatus\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"PatchOperation\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"Method\":\"PATCH\",\"Body\":null,\"Headers\":[]}},\"Client\":{\"marketplaceCountry\":\"US\",\"deviceFamily\":\"UniversalStore-PartnerCenter\",\"name\":\"Partner Center Web\"},\"Attributes\":{\"ObjectType\":\"Order\"}}",
"operationType": "create_order",
"originalCorrelationId": "96514ebe-c1b2-4865-cb46-2c2d20a2e911",
"operationDate": "2020-09-02T17:58:10.9268372Z",
"operationStatus": "succeeded",
"customizedData": [
{
"key": "OrderId",
"value": "Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1"
},
{
"key": "AlternateId",
"value": "64144d300bde"
},
{
"key": "BillingCycle",
"value": "Monthly"
},
{
"key": "OfferId-0",
"value": "DZH318Z0C964:0001:DZH318Z0BZDG"
},
{
"key": "SubscriptionId-0",
"value": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
},
{
"key": "SubscriptionName-0",
"value": "SaaS custom meter offer - Bronze"
},
{
"key": "Quantity-0",
"value": "1"
},
{
"key": "PartnerOnRecord-0",
"value": null
}
],
"attributes": {
"objectType": "AuditRecord"
}
},
{
"id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_86bddccf-9a53-40c6-907c-08067a3f8da7_86bddccf-9a53-40c6-907c-08067a3f8da7_addcustomer_637346648528069005",
"partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d",
"participants": [
"9daaeb1c-4195-4db5-9f1d-509eb70c8c2d"
],
"customerId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
"customerName": "CustomMetersStagingTest",
"userPrincipalName": "admin@testsw09.onmicrosoft.com",
"applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"resourceType": "customer",
"resourceNewValue": "{\"Id\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"CommerceId\":\"9dd78b4f-f98a-44b4-a2fa-2b82ac58d24c\",\"CompanyProfile\":{\"TenantId\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"Domain\":\"CustomMetersStagingTest.onmicrosoft.com\",\"CompanyName\":\"CustomMetersStagingTest\",\"Address\":null,\"Email\":null,\"OrganizationRegistrationNumber\":null,\"Links\":{\"Self\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/profiles/company\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]}},\"Attributes\":{\"ObjectType\":\"CustomerCompanyProfile\"}},\"BillingProfile\":{\"Id\":\"bbbbcccc-1111-dddd-2222-eeee3333ffff\",\"FirstName\":\"CustomMetersStagingTest\",\"LastName\":\"CustomMetersStagingTest\",\"Email\":\"CustomMetersStagingTest@CustomMetersStagingTest.com\",\"Culture\":\"en-US\",\"Language\":\"en\",\"CompanyName\":\"CustomMetersStagingTest\",\"DefaultAddress\":{\"Id\":null,\"Country\":\"US\",\"Region\":null,\"City\":\"Seattle\",\"State\":\"WA\",\"District\":null,\"AddressLine1\":\"CustomMetersStagingTest\",\"AddressLine2\":null,\"AddressLine3\":null,\"PostalCode\":\"98122\",\"FirstName\":\"CustomMetersStagingTest\",\"LastName\":\"CustomMetersStagingTest\",\"EmailAddress\":null,\"PhoneNumber\":null,\"MiddleName\":null},\"Attributes\":{\"Etag\":\"-2279334701316321663\",\"ObjectType\":\"CustomerBillingProfile\"}},\"RelationshipToPartner\":\"reseller\",\"AllowDelegatedAccess\":true,\"UserCredentials\":{\"userName\":\"admin\",\"password\":\"\"},\"AssociatedPartnerId\":null,\"CustomDomains\":null,\"Attributes\":{\"ObjectType\":\"Customer\"}}",
"operationType": "add_customer",
"originalCorrelationId": "7550d9ea-e64a-416f-e49b-3670c516cf69",
"operationDate": "2020-09-02T17:34:12.8069005Z",
"operationStatus": "succeeded",
"customizedData": [
{
"key": "PrimaryDomainName",
"value": "CustomMetersStagingTest.onmicrosoft.com"
},
{
"key": "Relationship",
"value": "Reseller"
}
],
"attributes": {
"objectType": "AuditRecord"
}
},
...
],
"links": {
"self": {
"uri": "/auditrecords?startDate=2020-09-02&endDate=2020-09-02&size=50",
"method": "GET",
"headers": []
}
},
"attributes": {
"objectType": "Collection"
}
}