グループに対する増分の変更を取得する

Microsoft Graph のデルタ クエリを使用すると、一連のデルタ要求を使用して、サポートされているリソースへの追加、削除、更新のクエリを実行できます。 グループの場合、デルタ クエリを使用すると、変更を比較するためにグループのセット全体をフェッチすることなく、変更を検出できます。

ローカル プロファイル ストアとグループを同期させるクライアントは、最初の完全同期とその後の増分同期の両方でデルタ クエリを使用できます。 通常、クライアントはテナント内のすべてのグループの初期完全同期を行い、グループに対する増分変更を定期的に取得します。

グループへの変更の追跡

delta 関数のある 1 つ以上の GET 要求でユーザーの変更を追跡します。 GET 要求には、次の特性があります。

  • URL パスの前に追加された デルタ 関数。
  • 前の GET デルタ関数呼び出しからの状態トークン (deltatoken または skiptoken)。
  • [省略可能]サポートされているクエリ パラメーター

この記事では、グループへの変更を追跡するための一連の要求例を示します。

  1. 最初の要求応答
  2. nextLink 要求応答
  3. 最後の nextLink 要求応答
  4. deltaLink 要求deltaLink 応答

最初の要求

グループ リソースの変更を追跡するには、要求を行い、URL セグメントとして delta 関数を含めます。

ヒント

/delta は完全修飾名のショートカットです /microsoft.graph.delta。 Microsoft Graph SDK によって生成された要求では、完全修飾名が使用されます。

以下の項目にご注意ください:

  • オプションの $select クエリ パラメーターが要求に含められているのは、クエリ パラメーターが将来の要求に自動的に含まれる方法を示すためです。 必要に応じて、クエリ パラメーターを最初の要求で指定する必要があります。
    • に含まれる $select プロパティのみが変更のために追跡されます。 が指定されていない場合 $select 、オブジェクトのすべてのプロパティが変更のために追跡されます。
  • オプションの $select クエリ パラメーターが使用されているのは、グループのメンバーをグループ オブジェクトと共に取り出す方法を示すためです。 この機能を使用すると、ユーザーがグループに追加または削除されたときなど、メンバーシップの変更を追跡できます。
  • 最初の要求には状態トークンは含まれません。 状態トークンは、後続の要求で使用されます。
GET https://graph.microsoft.com/v1.0/groups/delta?$select=displayName,description,members

最初の応答

成功した場合、このメソッドは 200 OK 応答コードと、応答本文で group コレクション オブジェクトを返します。 グループのセット全体が大きすぎて 1 つの応答に収まらない場合は、 @odata.nextLink 状態トークンを含む が含まれます。

この例では、セッションで取得するデータの追加ページがあることを示す @odata.nextLink URL が返されます。 URL 内の に $skiptoken 注目してください。 最初の要求の $select クエリ パラメーターは @odata.nextLink URL にエンコードされます。

プロパティは members@delta[すべての会社 ] グループに含まれ、グループの現在の 2 人のメンバーが含まれています。 sg-HR には、グループにメンバーがないため、そのプロパティは含まれません。

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

{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups(displayName,description)",
  "@odata.nextLink":"https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ",
  "value": [
    {
      "displayName":"All Company",
      "description":"This is the default group for everyone in the network",
      "id":"c2f798fd-f95d-4623-8824-63aec21fffff",
      "members@delta": [
               {
                   "@odata.type": "#microsoft.graph.user",
                   "id": "693acd06-2877-4339-8ade-b704261fe7a0"
               },
               {
                   "@odata.type": "#microsoft.graph.user",
                   "id": "49320844-be99-4164-8167-87ff5d047ace"
               }
      ]
    },
    {
      "displayName":"sg-HR",
      "description":"All HR personnel",
      "id":"ec22655c-8eb2-432a-b4ea-8b8a254bffff"
    }
  ]
}

2 番目の要求では、前の応答の @odata.nextLink を使用しています。それには、skiptoken が含まれています。 $select パラメーターは、エンコードされてトークンに含まれているため、目に見えて存在しないことに注意してください。

GET https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ

応答には、別の @odata.nextLink と新しい skiptoken 値が含まれています。これは、グループに対して追跡された変更がさらに使用可能であることを示します。 値が空の@odata.nextLink配列であっても、最後の応答で @odata.deltaLink URL (パラメーター内) が返されるまで@odata.deltaLink、後続の要求で URL を使用します。

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

{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups",
  "@odata.nextLink":"https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7",
  "value": [
    {
      "displayName":"Mark 8 Project Team",
      "description":"Mark 8 Project Team",
      "id":"2e5807ce-58f3-4a94-9b37-ffff2e085957",
      "members@delta": [
               {
                   "@odata.type": "#microsoft.graph.user",
                   "id": "632f6bb2-3ec8-4c1f-9073-0027a8c68593"
               }
      ]
    },
    {
      "displayName":"Sales and Marketing",
      "description":"Sales and Marketing",
      "id":"421e797f-9406-4934-b778-4908421e3505",
      "members@delta": [
               {
                   "@odata.type": "#microsoft.graph.user",
                   "id": "3c8ac7c4-d365-4df9-abfa-356a9dd7763c"
               },
               {
                   "@odata.type": "#microsoft.graph.user",
                   "id": "49320844-be99-4164-8167-87ff5d047ace"
               }
      ]
    }
  ]
}

3 番目の要求では、最後の同期要求から返された最新の @odata.nextLink を使用します。

GET https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=ppqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7

@odata.deltaLink URL が返された場合、グループ オブジェクトの既存の状態に関するデータはこれ以上ありません。 今後の要求では、アプリケーションは @odata.deltaLink URL を使用して、リソースへの変更点を確認します。 deltatoken を保存し、後続の要求 URL でそれを使用して、グループに対するその他の変更を検出します。

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

{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups",
  "@odata.deltaLink":"https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw",
  "value": [
    {
      "displayName":"All Employees",
      "id":"bed7f0d4-750e-4e7e-ffff-169002d06fc9"
    },
    {
      "displayName":"Remote living",
      "description":"Remote living",
      "id":"421e797f-9406-ffff-b778-4908421e3505"
    }
  ]
}

最後の応答から を @odata.deltaLink 使用して、 最後の要求以降にグループに対する変更 (追加、削除、または更新) を取得します。 変更内容には、次のものが含まれます。

  • 新たに作成されたグループ オブジェクト。
  • 削除されたグループ オブジェクト。
  • 追跡対象のプロパティが変更されたオブジェクト (更新された displayName など) をグループ化します。
  • メンバー オブジェクトが追加または削除されたグループ オブジェクト。
GET https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw

変更 @odata.deltaLink がない場合、 は結果なしで返されます。 value プロパティは空の配列です。 アプリケーションでは将来の呼び出しに備えて、以前のリンクを新しいリンクに必ず置き換えてください。

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

{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups",
  "@odata.deltaLink":"https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw",
  "value": []
}

変更がある場合は、変更されたグループのコレクションが含まれます。 さらに応答には、@odata.nextLink (取得対象の変更のページが複数ある場合) と @odata.deltaLink のどちらかも含まれています。 @odata.nextLink の後もそれまでと同じパターンを実装し、最後の @odata.deltaLink を将来の呼び出しに備えて保持しておいてください。

注:

この要求には、最近作成、更新、または削除されたグループのレプリケーションの遅延が発生する可能性があります。 しばらくしてから、@odata.nextLink または @odata.deltaLink を再試行して、最新の変更を取得してください。

応答の例に関して注意する必要がある点:

  • オブジェクトは、当初 $select のクエリ パラメーターで指定されたのと同じプロパティ セットを伴って返されます。
  • 変更されたプロパティと変更されていないプロパティの両方が含まれます。 description プロパティには新しい値が設定されていますが、 displayName プロパティは変更されていません。
  • members@delta には、グループ メンバーシップに対する次の変更が含まれています。
    • ID を 632f6bb2-3ec8-4c1f-9073-0027a8c6859 持つユーザーは、 プロパティで説明 @removed されているように、メンバーシップを削除することでグループから削除されました。 オブジェクトの削除によってグループから削除されたオブジェクトは、デルタ クエリでは検出されません。
    • ID 37de1ae3-408f-4702-8636-20824abda004 を持つ 2 番目のユーザーがグループに追加されました。

グループ オブジェクトには、次の @removed シナリオで注釈を含めることができます。

  • グループ (Microsoft 365 グループ) が削除されると、アイテムには注釈が含まれます: "reason": "changed" の値の注釈 @removed
  • グループが完全に削除された場合 (セキュリティ グループまたは Microsoft 365 グループを完全に削除する場合)、項目には注釈が含まれます。 @removed"reason": "deleted"は です。
  • グループが作成または復元されると、注釈は含まれません。
HTTP/1.1 200 OK
Content-type: application/json

{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups",
  "@odata.deltaLink":"https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw",
  "value": [
          {
              "displayName": "TestGroup3",
              "description": "A test group for change tracking",
              "id": "2e5807ce-58f3-4a94-9b37-ffff2e085957",
              "members@delta": [
                  {
                      "@odata.type": "#microsoft.graph.user",
                      "id": "632f6bb2-3ec8-4c1f-9073-0027a8c6859",
                      "@removed": {
                          "reason": "deleted"
                      }
                  },
                  {
                      "@odata.type": "#microsoft.graph.user",
                      "id": "37de1ae3-408f-4702-8636-20824abda004"
                  }
              ]
          }
      ]
}

大規模グループ内のメンバー間のページング

プロパティは members@delta 、既定では、クエリ パラメーターが指定されていない場合 $select 、またはパラメーターが明示的に指定されている場合 $select=members に、グループ オブジェクトに含まれます。 メンバーが多いグループの場合、すべてのメンバーが 1 つの応答に収まらない可能性があります。 このような場合を処理するには、次のパターンを実装します。

注:

このパターンは、グループ状態を最初に取得する際にも、それ以降にデルタ変更を取得するために呼び出す際にも適用されます。

グループの初期状態のすべてを取得するため、またはその後デルタ変更を取得するために、次のデータ クエリを実行していると想定しましょう:

GET https://graph.microsoft.com/v1.0/groups/delta?$select=displayName,description,members
  1. Microsoft Graph は、プロパティ内のメンバーの大きなリストを含む、1 つのグループ オブジェクトのみを含む応答を members@delta 返す場合があります。

最初のページ

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

{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups",
  "@odata.nextLink":"https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=<...>",
  "value": [
    {
      "displayName":"LargeGroup",
      "description":"A group containing thousands of users",
      "id":"2e5807ce-58f3-4a94-9b37-ffff2e085957",
      "members@delta": [
          {
              "@odata.type": "#microsoft.graph.user",
              "id": "632f6bb2-3ec8-4c1f-9073-0027a8c6859",
              "@removed": {
                  "reason": "deleted"
              }
          },
          {
              "@odata.type": "#microsoft.graph.user",
              "id": "37de1ae3-408f-4702-8636-20824abda004"
          },
          <...more users here...>
      ]
    }
    <...no more groups included - this group filled out the entire response...>
  ]
}
  1. @odata.nextLink従うと、同じグループ オブジェクトを含む応答を受け取ることがあります。 同じプロパティ値が返されますが、プロパティに members@delta 別のユーザーの一覧が含まれるようになりました。

2 番目のページ

HTTP/1.1 200 OK
Content-type: application/json
{
  "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#groups",
  "@odata.nextLink":"https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=<...>",
  "value": [
    {
      "displayName":"LargeGroup",
      "description":"A group containing thousands of users",
      "id":"2e5807ce-58f3-4a94-9b37-ffff2e085957",
      "members@delta": [
          {
              "@odata.type": "#microsoft.graph.user",
              "id": "c08a463b-7b8a-40a4-aa31-f9bf690b9551",
              "@removed": {
                  "reason": "deleted"
              }
          },
          {
              "@odata.type": "#microsoft.graph.user",
              "id": "23423fa6-821e-44b2-aae4-d039d33884c2"
          },
          <...more users here...>
      ]
    }
    <...no more groups included - this group filled out the entire response...>
  ]
}
  1. 最終的に、メンバー リスト全体がこの方法で返され、他のグループが応答に表示され始めます。

このパターンを処理する際には、次のベスト プラクティスに従うことをお勧めします。

  • 常に @odata.nextLink をたどり、各グループの状態をローカルでマージします。同じグループに関連する複数の応答を受信したなら、アプリケーションの中でその応答を使用してメンバーシップ リスト全体を作成します。
  • 応答の特定のシーケンスを想定しないでください。 @odata.nextLink シーケンスのどこにでも同じグループが出現する可能性があると想定し、マージ ロジックの中でそれを処理します。