Partager via


Effectuer des opérations conditionnelles à l’aide de l’API web

Microsoft Dataverse prend en charge un ensemble d’opérations conditionnelles qui s’appuient sur le mécanisme de gestion de version de ressources HTTP standard appelé ETags.

ETags

Le protocole HTTP définit une balise d’entité, ou ETag pour un court terme, pour identifier des versions spécifiques d’une ressource. Les ETags sont des identificateurs opaques dont les valeurs exactes dépendent de l’implémentation. Les valeurs ETag se produisent dans deux variétés : validation forte et faible. La validation forte indique qu’une ressource unique, identifiée par un URI spécifique, est identique au niveau binaire si sa valeur ETag correspondante est inchangée. La validation faible garantit uniquement que la représentation de ressource est sémantiquement équivalente pour la même valeur ETag.

Dataverse génère une propriété faiblement valide @odata.etag pour chaque instance d’entité, et cette propriété est automatiquement retournée avec chaque enregistrement d’entité récupéré. Pour plus d’informations, consultez Récupérer une ligne de table à l’aide de l’API web.

en-têtes If-Match et If-None-Match

Utilisez les en-têtes If-Match et If-None-Match avec des valeurs ETag pour vérifier si la version actuelle d'une ressource correspond à celle qui a été récupérée en dernier, à une version précédente quelconque, ou à aucune version. Ces comparaisons constituent la base de la prise en charge des opérations conditionnelles. Dataverse fournit des ETags pour prendre en charge des récupérations conditionnelles, l'accès concurrentiel optimiste et des opérations upsert limitées.

Avertissement

Le code client ne doit pas donner de signification à la valeur spécifique d’un ETag, ni à toute relation apparente entre ETags au-delà de l’égalité ou de l’inégalité. Par exemple, une valeur ETag pour une version plus récente d’une ressource n’est pas garantie d’être supérieure à la valeur ETag pour une version antérieure. En outre, l’algorithme utilisé pour générer de nouvelles valeurs ETag peut changer sans préavis entre les versions d’un service.

Récupérations conditionnelles

Les etags vous permettent d’optimiser les récupérations d’enregistrements chaque fois que vous accédez au même enregistrement plusieurs fois. Si vous avez précédemment récupéré un enregistrement, vous pouvez transmettre la valeur ETag avec l’en-tête If-None-Match pour demander des données à récupérer uniquement si elle a changé depuis la dernière récupération. Si les données ont changé, la requête retourne un état HTTP contenant 200 OK les données les plus récentes dans le corps de la requête. Si les données ne sont pas modifiées, le code 304 Not Modified d’état HTTP est retourné pour indiquer que l’enregistrement n’a pas été modifié.

L'exemple de paire de messages suivant retourne des données pour un enregistrement de compte dont la valeur accountid est égale à 00000000-0000-0000-0000-000000000001, lorsque les données n'ont pas changé depuis leur dernière récupération et que la valeur de l'Etag était W/"468026".

Requête :

GET [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001)?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue   HTTP/1.1  
Accept: application/json  
OData-MaxVersion: 4.0  
OData-Version: 4.0  
If-None-Match: W/"468026"  

Réponse:

HTTP/1.1 304 Not Modified  
Content-Type: application/json; odata.metadata=minimal  
OData-Version: 4.0  

Les sections suivantes décrivent les limitations relatives à l’utilisation des récupérations conditionnelles.

La table doit avoir l’accès concurrentiel optimiste activé

Vérifiez si une table dispose d’une concurrence optimiste activée à l’aide de la demande d’API web suivante. Les tables avec accès concurrentiel optimiste activé ont la propriété EntityMetadata.IsOptimisticConcurrencyEnabled définie sur true.

GET [Organization URI]/api/data/v9.2/EntityDefinitions(LogicalName='<Entity Logical Name>')?$select=IsOptimisticConcurrencyEnabled

La requête ne doit pas inclure $expand

L’Etag ne peut détecter que si l’enregistrement unique en cours de récupération a été modifié. Lorsque vous utilisez $expand votre requête, d’autres enregistrements peuvent être retournés et il n’est pas possible de détecter si l’un de ces enregistrements a été modifié ou non. Si la requête inclut $expand, 304 Not Modified n’est jamais retournée.

La requête ne doit pas inclure d’annotations

Quand l’en-tête Prefer: odata.include-annotations est inclus avec une requête GET, il ne renvoie jamais 304 Not Modified. Les valeurs des annotations peuvent faire référence à des valeurs provenant d’enregistrements associés. Ces enregistrements peuvent avoir changé et cette modification n’a pas pu être détectée. Il serait donc incorrect d’indiquer que rien n’a changé.

Limiter les opérations upsert

Un upsert fonctionne généralement en créant un enregistrement s’il n’existe pas ; sinon, il met à jour un enregistrement existant. Toutefois, les ETags peuvent être utilisés pour contraindre davantage les upserts à empêcher des créations ou à empêcher des mises à jour.

Éviter la création dans upsert

Si vous mettez à jour des données et que l’enregistrement a été supprimé intentionnellement, vous ne souhaitez pas recréer l’enregistrement. Pour éviter cela, ajoutez un en-tête If-Match à la demande avec la valeur *.

Requête :

PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1  
Content-Type: application/json  
OData-MaxVersion: 4.0  
OData-Version: 4.0  
If-Match: *  
  
{  
    "name": "Updated Sample Account ",  
    "creditonhold": true,  
    "address1_latitude": 47.639583,  
    "description": "This is the updated description of the sample account",  
    "revenue": 6000000,  
    "accountcategorycode": 2  
}  

Réponse:

Si l’enregistrement est trouvé, vous obtenez une réponse normale avec l’état 204 No Content. Lorsque l’enregistrement est introuvable, vous obtenez la réponse suivante avec l’état 404 Not Found.

HTTP/1.1 404 Not Found  
OData-Version: 4.0  
Content-Type: application/json; odata.metadata=minimal  
  
{  
 "error": {  
  "code": "",  
  "message": "account With Id = 00000000-0000-0000-0000-000000000001 Does Not Exist"
 }  
}  

Éviter la mise à jour dans upsert

Si vous insérez des données, il est possible qu’un enregistrement avec la même id valeur existe déjà dans le système et que vous ne souhaitiez peut-être pas le mettre à jour. Pour éviter cela, ajoutez un If-None-Match en-tête à la demande avec la valeur « * ».

Requête :

PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1  
Content-Type: application/json  
OData-MaxVersion: 4.0  
OData-Version: 4.0  
If-None-Match: *  
  
{  
    "name": "Updated Sample Account ",  
    "creditonhold": true,  
    "address1_latitude": 47.639583,  
    "description": "This is the updated description of the sample account",  
    "revenue": 6000000,  
    "accountcategorycode": 2  
}  

Réponse:
Si l’enregistrement est introuvable, vous obtiendrez une réponse normale avec l’état 204 No Content. Une fois l’enregistrement trouvé, vous obtenez la réponse suivante avec l’état 412 Precondition Failed.

HTTP/1.1 412 Precondition Failed  
OData-Version: 4.0  
Content-Type: application/json; odata.metadata=minimal  
  
{  
  "error":{  
   "code":"",  
   "message":"A record with matching key values already exists."
  }  
}  

Appliquer la concurrence optimiste

Vous pouvez utiliser la concurrence optimiste pour détecter si un enregistrement a été modifié depuis qu'il a été récupéré pour la dernière fois. Si l’enregistrement que vous envisagez de mettre à jour ou de supprimer a changé sur le serveur depuis que vous l’avez récupéré, vous ne souhaiterez peut-être pas terminer l’opération de mise à jour ou de suppression. En appliquant le modèle indiqué ici, vous pouvez détecter cette situation, récupérer la version la plus récente de l’enregistrement et appliquer tous les critères nécessaires pour réévaluer s’il faut réessayer l’opération.

Appliquer l’accès concurrentiel optimiste sur la suppression

La demande de suppression suivante pour un compte avec accountid00000000-0000-0000-0000-000000000001 échoue car la valeur ETag envoyée avec l'en-tête If-Match est différente de la valeur actuelle. Si la valeur correspond, un 204 No Content statut est attendu.

Requête :

DELETE [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1  
If-Match: W/"470867"  
Accept: application/json  
OData-MaxVersion: 4.0  
OData-Version: 4.0  

Réponse:

HTTP/1.1 412 Precondition Failed  
Content-Type: application/json; odata.metadata=minimal  
OData-Version: 4.0  
  
{  
  "error":{  
    "code":"","message":"The version of the existing record doesn't match the RowVersion property provided." 
  }  
}  

Appliquer l’accès concurrentiel optimiste sur la mise à jour

La demande de mise à jour suivante pour un compte avec accountid de 00000000-0000-0000-0000-000000000001 échoue, car la valeur ETag envoyée avec l’en-tête If-Match est différente de la valeur actuelle. Si la valeur correspond, un 204 No Content statut est attendu.

Requête :

PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1  
If-Match: W/"470867"  
Accept: application/json  
OData-MaxVersion: 4.0  
OData-Version: 4.0  
  
{"name":"Updated Account Name"}  

Réponse:

HTTP/1.1 412 Precondition Failed  
Content-Type: application/json; odata.metadata=minimal  
OData-Version: 4.0  
  
{  
  "error":{  
    "code":"","message":"The version of the existing record doesn't match the RowVersion property provided."
  }  
}  

Voir aussi

Exemple d’opérations conditionnelles de l’API Web (C#)
Exemple d′opérations conditionnelles de l′API Web (Javascript côté client)
Effectuer des opérations à l’aide de l’API Web
Composer des demandes Http et gérer les erreurs
Interroger les données à l’aide de l’API Web
Créer une ligne de table à l’aide de l’API web
Récupérer une ligne de table à l’aide de l’API Web
Mettre à jour et supprimer des lignes de table à l’aide de l’API web
Associer et dissocier des lignes de tables à l’aide de l’API Web
Utiliser des fonctions API Web
Utiliser des actions API Web
Exécuter des opérations par lots à l’aide de l’API Web
Emprunter l’identité d’un autre utilisateur à l’aide de l’API Web