Web API を使用する条件付き演算を実行する

 

公開日: 2017年1月

対象: Dynamics 365 (online)、Dynamics 365 (on-premises)、Dynamics CRM 2016、Dynamics CRM Online

Microsoft Dynamics 365 により、ETags として知られている標準 HTTP リソースのバージョン管理メカニズムに依存する条件付き演算のセットをサポートします。

このトピックの内容

ETag

If-Match ヘッダーおよび If-None-Match ヘッダー

条件付き検索

upsert 操作の制限

オプティミスティック同時実行の適用

ETag

HTTP プロトコルは、リソースの特定のバージョンを識別するために、エンティティ タグ または省略して、ETag を定義します。 ETags は不透明の識別子であるため、その正確な値は実装に依存します。 ETag 値は 2 つの種類で表示されます: 厳密と緩い検証です。 厳密検証により、特定の URI によって識別されるユニークなリソースは、対応する ETag の値が変わらない場合は、バイナリ レベル上同一となることが示されています。 緩い検証は、同じ ETag の値におけるリソースの表示は、意味的に同等であることを保証するのみです。

Dynamics 365 により、各エンティティ インスタンスに対して軽く検証する @odata.etag プロパティが生成され、このプロパティは取得した各エンティティ レコードに自動で返されます。 詳細については、「Web API を使用してエンティティを取得する」を参照してください。

If-Match ヘッダーおよび If-None-Match ヘッダー

If-MatchIf-None-Match ヘッダーを ETag の値と共に使用し、リソースの現在のバージョンが最後に取得したものと一致するか、以前のバージョンと一致するか、またはすべてのバージョンと一致しないかを確認します。 これらの比較を行うことによって、条件付きの操作サポートのベースが作られます。 Dynamics 365 は ETags を使用して、条件付きの検索、オプティミスティック同時実行、および制限付き upsert 操作をサポートします。

警告

クライアント コードは ETag の特定値に、または平等または不平等以外の ETag 間の明確な関連付けに意味を持たせることはできません。 たとえば、リソースの新バージョンの ETag 値がそれ以前のバージョンの ETag 値を超えることは保証されません。 また、新しい ETag 値を生成するのに使用されるアルゴリズムはサービスのリリース通知なしに変更する場合があります。

条件付き検索

Etags により、同じレコードに複数回アクセスするときは、いつでもレコードの検索を最大限に活用することができます。 以前にレコードを取得している場合、最後に取得されてから変更している場合にのみ、取得されたデータを要求するために、If-None-Match ヘッダーを含む ETag 値を渡すことができます。 データが変更されている場合、要求は、要求の本体の最新データを含む 200 (OK) HTTP ステータスを返します。 データが変更されていない場合、エンティティが変更されていないことを示す HTTP ステータス コード 304 (Not Modified) が返されます。 次のサンプルのメッセージ ペアは、データが最後に取得されて以来変更されていない場合、00000000-0000-0000-0000-000000000001 に等しい accountid を含む取引先企業エンティティのデータを返します。

  • 要求

    GET cc_WebAPI_ServiceURI/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"
    
  • 応答

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

upsert 操作の制限

upsert は、エンティティが存在しない場合にエンティティを作成することによって本来機能します。それ以外の場合は、既存のエンティティを更新します。 ただし、作成または更新のいずれかを阻止するために、ETags は upserts をさらに制限するのに使用できます。

upsert での作成の阻止

データを更新するとき、エンティティが意識して削除された可能性が見られる場合、そのエンティティの再作成を望まないでしょう。 これを阻止するには、If-Match ヘッダーを "*" の値を持つ要求に追加します。

  • 要求

    PATCH cc_WebAPI_ServiceURI/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
    }
    
  • 応答
    エンティティが存在する場合、ステータス 204 (No Content) を含む通常応答を受け取ります。 エンティティが存在しない場合は、ステータス 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",
      "innererror": {
       "message": "account With Id = 00000000-0000-0000-0000-000000000001 Does Not Exist",
       "type": "System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
       "stacktrace": <stack trace removed for brevity>
      }
     }
    }
    

upsert での更新の阻止

データを挿入する場合、同じ id 値を持つレコードがシステムにすでに存在している可能性があり、その更新を望まないでしょう。 これを阻止するには、If-None-Match ヘッダーを "*" の値を持つ要求に追加します。

  • 要求

    PATCH cc_WebAPI_ServiceURI/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
    }
    
  • 応答
    エンティティが存在しない場合は、ステータス 204 (No Content) を含む通常応答を受け取ります。 エンティティが存在する場合は、ステータス 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.",
       "innererror":{
        "message":"Cannot insert duplicate key.",
        "type":"System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
        "stacktrace":<stack trace removed for brevity>
        }
      }
    }
    

オプティミスティック同時実行の適用

最後に取得されてからエンティティが変更されているかどうかを検出するためにオプティミスティック同時実行を使用できます。 更新または削除するエンティティが、取得して以降サーバー上で変更された場合、更新または削除操作を完了させない方が望ましいでしょう。 ここに示すパターンを適用することによって、この状態の検出、エンティティの最新バージョンの取得、操作をやり直すかどうかを再評価するために必要な条件の適用を行うことができます。

削除でのオプティミスティック同時実行の適用

accountid of00000000-0000-0000-0000-000000000001 の取引先企業の以下の削除要求は、If-Match ヘッダーと共に送信される ETag 値が現在の値とは異なるので失敗します。 値が一致する場合、204 (No Content) ステータスが予想されます。

  • 要求

    DELETE cc_WebAPI_ServiceURI/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
    If-Match: W/"470867"
    Accept: application/json
    OData-MaxVersion: 4.0
    OData-Version: 4.0
    
  • 応答

    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.",
        "innererror":{
          "message":"The version of the existing record doesn't match the RowVersion property provided.",
          "type":"System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
    "stacktrace":"  <stack trace details omitted for brevity>
        }
      }
    }
    

更新でのオプティミスティック同時実行の適用

00000000-0000-0000-0000-000000000001 の accountid 取引先企業の以下の更新要求は、If-Match ヘッダーと共に送信される ETag 値が現在の値とは異なるので失敗します。 値が一致する場合、204 (No Content) 状態になります。

  • 要求

    PATCH cc_WebAPI_ServiceURI/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"}
    
  • 応答

    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.",
        "innererror":{
          "message":"The version of the existing record doesn't match the RowVersion property provided.",
          "type":"System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
    "stacktrace":"  <stack trace details omitted for brevity>
        }
      }
    }
    

関連項目

Web API 条件付き演算サンプル (C#)
Web API 条件付き演算のサンプル (クライアント側の JavaScript)
Web API を使用して演算を実行する
HTTP 要求の作成とエラーの処理
Web API を使用したクエリ データ
Web API を使用してエンティティを作成する
Web API を使用してエンティティを取得する
Web API を使用したエンティティの更新と削除
Web API を使用したエンティティの関連付けと関連付け解除
Web API 関数の使用
Web API アクションの使用
Web API を使用してバッチ操作を実行する
Web API を使用して別のユーザーを偽装する

Microsoft Dynamics 365

© 2017 Microsoft. All rights reserved. 著作権