次の方法で共有


JSON バッチ処理を使用して複数の HTTP 要求を結合する

JSON バッチ処理を使用すると、クライアントは複数の要求を 1 つの JSON オブジェクトと 1 つの HTTP 呼び出しに結合できるため、ネットワークラウンドトリップが削減され、効率が向上します。 Microsoft Graph では、最大 20 個の要求を JSON オブジェクトにバッチ処理できます。

この記事では、JSON バッチ処理の基本、動作方法、およびそれを使用してアプリケーションを最適化する方法について説明します。

注:

Microsoft Graph では、JSON バッチ処理をサポートするために、 $batchOData URL パス セグメント が実装されています。

シナリオ例

次の無関係なデータのビューを作成するクライアントを考えてみましょう。

  • OneDrive に保存されているイメージ
  • Planner タスクのリスト
  • グループの予定表

これらの 3 つの要求を 1 つのバッチ要求にまとめることで、ネットワーク待機時間を大きく削減できます。

バッチ要求の作成

バッチ要求を作成するには:

  1. 要求 HTTP メソッドを POST として指定 します

  2. v1.0または beta バージョンの Microsoft Graph を対象にした URL エンドポイントを指定し、$batch セグメントを URL に追加します。 つまり、 https://graph.microsoft.com/v1.0/$batch

  3. バッチ要求本文を次のように定義します。

    1. JSON バッチ要求本文は、要求という 1 つの必須プロパティを持つ 1 つの JSON オブジェクトで構成 されます。 このプロパティは、個々の要求のコレクションです。
    2. 個々の要求ごとに、次のプロパティを渡すことができます。
    プロパティ 説明
    id 必須です。 文字列。 個々の応答を要求に関連付ける相関値。 この値を使用すると、サーバーはバッチ内の要求を最も効率的な順序で処理できます。 大文字と小文字は区別されません。 バッチ内で一意である必要があります。それ以外の場合、バッチ要求は 400 エラー コードで失敗します。
    メソッド 必須です。 URL で指定された要求に対してサポートされる HTTP メソッド。
    url 必須です。 個々の要求の相対リソース URL。 したがって、絶対 URL はhttps://graph.microsoft.com/v1.0/usersであるのに対し、この URL は/usersです。
    ヘッダー オプションですが、 本文 を指定した場合は必須です。 ヘッダーのキーと値のペアを持つ JSON オブジェクト。 たとえば、 ConsistencyLevel ヘッダーが必要な場合、このプロパティは "headers": {"ConsistencyLevel": "eventual"}として表されます。 本文 を指定する場合は、 Content-Type ヘッダーを含める必要があります。
    body 省略可能。 JSON オブジェクトまたは base64 URL でエンコードされた値 (本文がイメージの場合など) の場合があります。 本文 が要求に含まれている場合、ヘッダー オブジェクトには、Content-Type の値を含める必要があります。

JSON バッチ要求の例

この例のシナリオでは、JSON バッチ要求を作成します。 個々の要求は相互に依存しないため、任意の順序でバッチ要求に配置できます。

POST https://graph.microsoft.com/v1.0/$batch
Accept: application/json
Content-Type: application/json

{
  "requests": [
    {
      "id": "1",
      "method": "GET",
      "url": "/me/memberOf"
    },
    {
      "id": "2",
      "method": "GET",
      "url": "/me/planner/tasks"
    },
    {
      "id": "3",
      "method": "DELETE",
      "url": "/groups/0e226165-c685-41ce-8bfc-df8360ab325d"
    },
    {
      "id": "4",
      "url": "/users/161ab652-cdbc-490d-82a4-0ada1f0db247/getPasswordSingleSignOnCredentials",
      "method": "POST",
      "body": {},
      "headers": {"Content-Type": "application/json"}
    },
    {
      "id": "5",
      "url": "users?$select=id,displayName,userPrincipalName&$filter=city eq null&$count=true",
      "method": "GET",
      "headers": {
        "ConsistencyLevel": "eventual"
      }
    }
  ]
}

JSON バッチ応答の処理

JSON バッチ要求の応答形式は、次のように要求形式とは異なります。

  • メイン JSON オブジェクトのプロパティには、要求 ではなく、応答 と命名されています。
  • 個々の応答は、要求と異なる順序で返されることがある。 id プロパティを使用して、個々の要求と応答を関連付けることができます。
  • 個々の応答には、 メソッドURL ではなく status プロパティがあります。 status の値は HTTP 状態コードです。
  • 個々の応答の ヘッダー プロパティは、サーバーによって返されるヘッダーを表します。 たとえば、Cache-Control および Content-Type ヘッダーなどです。

バッチ応答の状態コードは、通常 200 または 4xx です。 バッチ要求自体が正しい形式でない場合、状態コードは 400 になります。 バッチ要求が解析可能であれば、状態コードは 200 になります。 バッチ応答ヘッダーの 200 状態コードは、バッチ内の個々の要求が成功したことを示すわけではありません。 これが、 responses プロパティの個々の応答に状態コードがある理由です。

JSON バッチ応答の例

前の例では、次の応答を想定しています。

HTTP/1.1 200 OK
Content-Type: application/json

{
    "responses": [
        {
            "id": "1",
            "status": 200,
            "headers": {
                "Cache-Control": "no-cache",
                "x-ms-resource-unit": "1",
                "OData-Version": "4.0",
                "Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8"
            },
            "body": {
                "@odata.context": "https://graph.microsoft.com/beta/$metadata#directoryObjects",
                "@odata.nextLink": "https://graph.microsoft.com/beta/me/memberOf?$top=1&$skiptoken=RFNwdAoAAQAAAAAAAAAAFAAAAI45VMy0CO9Ei1L3Lr1q95UBAAAAAAAAAAAAAAAAAAAXMS4yLjg0MC4xMTM1NTYuMS40LjIzMzEGAAAAAAABURXWGePFEEGbudEn3SOTuQEDAQAAAQAAAAA",
                "value": [
                    {
                        "@odata.type": "#microsoft.graph.directoryRole",
                        "id": "21004afc-7bb2-4fe6-a1e1-074ebd3e52c1",
                        "deletedDateTime": null,
                        "description": "Can manage all aspects of users and groups, including resetting passwords for limited admins.",
                        "displayName": "User Administrator",
                        "roleTemplateId": "fe930be7-5e62-47db-91af-98c3a49a38b1"
                    }
                ]
            }
        },
        {
            "id": "2",
            "status": 403,
            "headers": {
                "Cache-Control": "no-cache",
                "X-ProxyCluster": "wus-001.tasks.osi.office.net",
                "X-OfficeCluster": "wus-001.tasks.osi.office.net",
                "X-Tasks-CorrelationId": "18a8e521-78a4-4129-9b6b-d678116464e7",
                "Content-Type": "application/json"
            },
            "body": {
                "error": {
                    "code": "",
                    "message": "You do not have the required permissions to access this item.",
                    "innerError": {
                        "date": "2025-02-13T10:17:05",
                        "request-id": "93b6f17e-c05d-4f45-ad2a-6665c708d8a0",
                        "client-request-id": "e70c5c1b-8b47-68c0-3171-3d22f5e0bd54"
                    }
                }
            }
        },
        {
            "id": "3",
            "status": 403,
            "headers": {
                "Cache-Control": "no-cache",
                "x-ms-resource-unit": "1",
                "Content-Type": "application/json"
            },
            "body": {
                "error": {
                    "code": "Authorization_RequestDenied",
                    "message": "Insufficient privileges to complete the operation.",
                    "innerError": {
                        "date": "2025-02-13T10:17:06",
                        "request-id": "93b6f17e-c05d-4f45-ad2a-6665c708d8a0",
                        "client-request-id": "e70c5c1b-8b47-68c0-3171-3d22f5e0bd54"
                    }
                }
            }
        },
        {
            "id": "4",
            "status": 405,
            "headers": {
                "Cache-Control": "no-cache",
                "x-ms-resource-unit": "1",
                "Content-Type": "application/json"
            },
            "body": {
                "error": {
                    "code": "Request_BadRequest",
                    "message": "Specified HTTP method is not allowed for the request target.",
                    "innerError": {
                        "date": "2025-02-13T10:21:18",
                        "request-id": "3a3b1bf7-3596-4493-8264-de81e028071f",
                        "client-request-id": "e5f9a304-2796-b7e8-ccce-dd989953ebc4"
                    }
                }
            }
        },
        {
            "id": "5",
            "status": 200,
            "headers": {
                "Cache-Control": "no-cache",
                "x-ms-resource-unit": "1",
                "OData-Version": "4.0",
                "Content-Type": "application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8"
            },
            "body": {
                "@odata.context": "https://graph.microsoft.com/beta/$metadata#users(id,displayName,userPrincipalName)",
                "@odata.count": 36,
                "value": [
                    {
                        "id": "10a1d484-cd1a-4162-a5a4-832370bac356",
                        "displayName": "Lynne Robbins",
                        "userPrincipalName": "LynneR@contoso.com"
                    }
                ]
            }
        }
    ]
}

バッチ応答の例での個々の応答の説明

  • 200状態コードに示すように、要求 1 と要求 5 が成功しました。
  • 要求 2 と 3 は、呼び出し元に必要なアクセス許可がないため、 403 状態コードで失敗しました。
  • 要求の url プロパティに指定されたエンドポイントが現在、まだ要求 URL が Microsoft Graph のv1.0 エンドポイントをターゲットbetaであるため、要求 4 は405状態コードで失敗しました。 ターゲット URL には要求本文は必要ありませんが、本文のみを空のオブジェクトにできるヘッダー本文のパラメーターを指定する必要があります。

dependsOn プロパティによる要求の順序指定

dependsOn プロパティを使用して、指定した順序で実行するバッチ内の要求を指定できます。 このプロパティは、異なる個々の要求の ID を 参照する文字列の配列です。 たとえば、次の要求では、クライアントは、要求を注文要求 1 で実行し、要求 2、要求 4、要求 3 で実行する必要があることを指定しています。

{
  "requests": [
    {
      "id": "1",
      "method": "GET",
      "url": "..."
    },
    {
      "id": "2",
      "dependsOn": [ "1" ],
      "method": "GET",
      "url": "..."
    },
    {
      "id": "4",
      "dependsOn": [ "2" ],
      "method": "GET",
      "url": "..."
    },
    {
      "id": "3",
      "dependsOn": [ "4" ],
      "method": "GET",
      "url": "..."
    }
  ]
}

個々の要求が失敗した場合、その要求に依存するすべての要求が失敗し、ステータス コードは 424 (Failed Dependency) になります。

ヒント

バッチは、完全シーケンシャルまたは完全パラレルである必要があります。

バッチ処理による URL 長さ制限の回避

JSON バッチ処理のもう 1 つのユース ケースは、URL の長さの制限をバイパスすることです。 フィルター句が複雑な場合、URL の長さは、ブラウザーやその他の HTTP クライアントに組み込まれている制限を超える可能性があります。 長い URL は単に要求ペイロードの一部になるため、これらの要求を実行するための回避策として JSON バッチ処理を使用できます。

バッチ サイズの制限

  • 現段階では、JSON バッチ要求は 20 個までの個別要求に限られています。
  • バッチ要求の一部である API に応じて、 基になるサービス は、Microsoft Graph を使用してそれらにアクセスするアプリケーションに影響を与える独自の調整制限を課します。
  • バッチ内の要求は、該当する調整制限に対して個別に評価され、要求が制限を超えると、 429の状態で失敗します。

詳細についてはThrottling and batchingを参照してください。

既知の問題

バッチ処理に関連する現在の制限事項の一覧は「既知の問題」を参照してください。