JSON バッチ処理を使用して複数の HTTP 要求を結合する
JSON バッチ処理を使用すると、クライアントは複数の要求を 1 つの JSON オブジェクトと 1 つの HTTP 呼び出しに結合できるため、ネットワークラウンドトリップが削減され、効率が向上します。 Microsoft Graph では、最大 20 個の要求を JSON オブジェクトにバッチ処理できます。
この記事では、JSON バッチ処理の基本、動作方法、およびそれを使用してアプリケーションを最適化する方法について説明します。
注:
Microsoft Graph では、JSON バッチ処理をサポートするために、 $batch
OData URL パス セグメント が実装されています。
シナリオ例
次の無関係なデータのビューを作成するクライアントを考えてみましょう。
- OneDrive に保存されているイメージ
- Planner タスクのリスト
- グループの予定表
これらの 3 つの要求を 1 つのバッチ要求にまとめることで、ネットワーク待機時間を大きく削減できます。
バッチ要求の作成
バッチ要求を作成するには:
要求 HTTP メソッドを POST として指定 します。
v1.0
またはbeta
バージョンの Microsoft Graph を対象にした URL エンドポイントを指定し、$batch
セグメントを URL に追加します。 つまり、https://graph.microsoft.com/v1.0/$batch
。バッチ要求本文を次のように定義します。
- JSON バッチ要求本文は、要求という 1 つの必須プロパティを持つ 1 つの JSON オブジェクトで構成 されます。 このプロパティは、個々の要求のコレクションです。
- 個々の要求ごとに、次のプロパティを渡すことができます。
プロパティ 説明 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を参照してください。
既知の問題
バッチ処理に関連する現在の制限事項の一覧は「既知の問題」を参照してください。