获取组的增量更改Get incremental changes for groups

Delta 查询可通过调用一系列的 delta 函数来查询组的添加、删除或更新。增量查询使你无需读取 Microsoft Graph 的整个组就能够发现组的更改并进行比较。Delta query lets you query for additions, deletions, or updates to groups, by way of a series of delta function calls. Delta query enables you discover changes to groups without having to fetch the entire set of groups from Microsoft Graph and compare changes.

以后,对本地配置文件存储使用同步组功能的客户端可以将增量查询用于初始完全同步和增量同步。通常,客户会对租户中的所有组进行初始完全同步,之后定期获取对组的增量更改。Clients using synchronizing groups with a local profile store can use Delta Query for both their initial full synchronization along with incremental synchronizations in the future. Typically, a client would do an initial full synchronization of all the groups in a tenant, and subsequently, get incremental changes to groups periodically.

跟踪组更改Tracking group changes

跟踪组更改是发出 delta 函数的一个或多个 GET 请求。发出 GET 请求与列出组的方式非常相似,除了要包括以下内容:Tracking group changes is a round of one or more GET requests with the delta function. You make a GET request much like the way you list groups, except that you include the following:

  • delta 函数。The delta function.
  • 上一个 GET delta 函数调用的状态令牌deltaTokenskipToken)。A state token (deltaToken or skipToken) from the previous GET delta function call.

示例Example

以下示例显示跟踪组更改的一系列请求:The following example shows a series requests to track changes to groups:

  1. 初始请求响应Initial request and response
  2. nextLink 请求响应nextLink request and response
  3. 最终 nextLink 请求响应Final nextLink request and response
  4. deltaLink 请求deltaLink 响应deltaLink request and deltaLink response

初始请求Initial request

为开始跟踪组资源的更改,请在组资源上发出包含 delta 函数的请求。To begin tracking changes in the group resource, you make a request including the delta function on the group resource.

请注意以下几点:Note the following:

  • 请求中包含可选的 $select 查询参数,以演示如何在以后的请求中自动包含查询参数。The optional $select query parameter is included in the request to demonstrate how query parameters are automatically included in future requests.
  • 可选的 $select 查询参数还用于显示如何一起检索组成员和组对象。The optional $select query parameter is also used to show how group members can be retrieved together with group objects. 这允许跟踪成员身份变更,例如当用户被添加到组或从组中删除时。This allows tracking of membership changes, such as when users are added or removed from groups.
  • 初始请求不包括状态令牌。状态令牌将用于后续请求中。The initial request does not include a state token. State tokens will be used in subsequent requests.
GET https://graph.microsoft.com/v1.0/groups/delta?$select=displayName,description,members

初始响应Initial response

如果成功,此方法在响应正文中返回 200 OK 响应代码和集合对象。If successful, this method returns 200 OK response code and group collection object in the response body. 如果整个组集过大而无法适应一个响应,那么还将包括一个包含状态令牌的 nextLinkIf the entire set of groups is too large to fit in one response, a nextLink containing a state token will also be included.

此示例中包含 nextLink;原始 $select 查询参数则在状态令牌中进行了编码。In this example, a nextLink was included; the original $select query parameter is encoded in the state token.

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":"TestGroup1",
      "description":"Employees in test group 1",
      "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":"TestGroup2",
      "description":"Employees in test group 2",
      "id":"ec22655c-8eb2-432a-b4ea-8b8a254bffff"
    }
  ]
}

注意:members@delta 属性包含在第一个组对象 (TestGroup1) 中,并包含此组的两个当前成员。Note: The members@delta property is included in the first group object - TestGroup1 - and contains the two current members of the group. TestGroup2 不包含此属性,因为组中没有任何成员。TestGroup2 does not contain that property because the group does not have any members.

第二个请求使用上一个响应中的 nextLink,其中包含 skipTokenThe second request uses the nextLink from the previous response, which contains the skipToken. 请注意,$select 参数不显式出现,因为它在令牌中编码。Notice the $select parameter is not explicitly present as it is encoded in the token.

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

该响应包含另一个带新 skipToken 值的 nextLink,它表示存在更多可用的组。The response contains another nextLink with a new skipToken value, which indicates that more groups are available. 应使用 nextLink URL 继续发出请求,直到在最终响应中返回 deltaLink URL,即使该值为空数组(在某些情况下可能会出现此情况)。You should continue making requests using the nextLink URL until a deltaLink URL is returned in the final response, even if the value is an empty array (this can happen under certain circumstances).

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":"TestGroup3",
      "description":"Employees in test group 3",
      "id":"2e5807ce-58f3-4a94-9b37-ffff2e085957",
      "members@delta": [
               {
                   "@odata.type": "#microsoft.graph.user",
                   "id": "632f6bb2-3ec8-4c1f-9073-0027a8c68593"
               }
      ]
    },
    {
      "displayName":"TestGroup4",
      "description":"Employees in test group 4",
      "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"
               }
      ]
    }
  ]
}

第三个请求再次使用最新的 nextLinkThe third request again uses the latest nextLink.

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

最后返回 deltaLink URL,这意味着没有更多数据反映现有的组状态。Finally, the deltaLink URL is returned, which means there is no more data for the existing state of groups. 对于将来请求,应用程序将使用它所包含的 deltaLinkdeltaToken 值来了解有关组的新更改。For future requests, the application uses the deltaLink and the deltaToken value it contains to learn about new changes to groups.

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":"TestGroup5",
      "description":"Employees in test group 5",
      "id":"bed7f0d4-750e-4e7e-ffff-169002d06fc9"
    },
    {
      "displayName":"TestGroup6",
      "description":"Employees in test group 6",
      "id":"421e797f-9406-ffff-b778-4908421e3505"
    }
  ]
}

通过使用上次响应deltaLink,你将能够获取自上次请求以来对组所做的新更改。Using the deltaLink from the last response, you will be able to get net new changes to groups since the last request. 这些更改包括:Changes include:

  • 新创建的组对象。Newly created group objects.
  • 已删除的组对象。Deleted group objects.
  • 属性已更改的组对象(例如,修改了 displayName)。Group objects for which a property has changed (e.g. displayName has been modified).
  • 已为其添加或移除成员对象的组对象。Group objects for which member objects have been added or removed.
GET https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw

如果未发生更改,则会返回 deltaLink 且无返回结果 - value 属性为空。If no changes have occurred, a deltaLink is returned with no results - the value property is empty. 请确保将应用程序中的以前链接替换为新链接以便在日后调用中使用。Make sure to replace the previous link in the application with the new one for use in future calls.

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": []
}

如果发生更改,则包含已更改组的集合。If changes have occurred, a collection of changed groups is included. 响应还包含 nextLinkdeltaLink(如果要检索多个更改页面)。The response also contains either a nextLink - in case there are multiple pages of changes to retrieve - or a deltaLink. 应像以前一样实现遵循 nextLinks 的相同模式,并保留最终的 deltaLink 供日后调用。You should implement the same pattern of following the nextLinks as before and persist the final deltaLink for future calls.

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"
                  }
              ]
          }
      ]
}

上面示例响应的一些注意事项如下:Some things to note about the example response above:

  • 这些对象连同一组相同的属性一起返回,这些属性最初通过 $select 查询参数指定。The objects are returned with the same set of properties originally specified via the $select query parameter.

  • 同时包括更改和未更改的属性。Both changed and unchanged properties are included. 在上述示例中,description 属性具有新值,而 displayName 属性未发生更改。In the example above, the description property has a new value, while the displayName property has not changed.

  • members@delta 包含对成员身份的任何更改。members@delta contains any changes to membership.

    • 列表中的第一个用户已经从组中删除 - 要么删除成员身份,要么删除用户对象本身。The first user in the list has been removed from the group - either by removing the membership or by deleting the user object itself. @removed 属性对此进行了说明。The @removed property describes that. 只有被永久删除的用户才会从组中删除。Only users that have been permanently deleted are removed from groups. 临时删除的用户保留自己的组成员资格,除非被永久删除,否则不会显示在增量结果中。Users that have been temporary deleted keep their group memberships and will not appear in the delta result until they are permanently deleted. 有关详细信息,请参阅目录(已删除的项)For details, see directory (deleted items).

    • 第二个用户已添加到组。The second user has been added to the group.

逐页查看大型组中的成员Paging through members in a large group

当未指定 $select 查询参数,或已显式指定 $select=members 参数时,members@delta 属性默认包含在组对象中。The members@delta property is included in group objects by default, when the $select query parameter has not been specified, or when the $select=members parameter is explicitly specified. 对于包含许多成员的组来说,可能所有成员都无法适应单个响应;在本节中,我们将介绍为处理这种情况所应实现的模式。For groups with many members it is possible that all members cannot fit into a single response; in this section we describe the pattern you should implement to handle such cases.

注意: 此模式既适用于组状态的初始检索,也适用于后续调用,以获取增量更改。Note: This pattern applies to both the initial retrieval of group state as well as to subsequent calls to get delta changes.

假定正在执行以下增量查询 - 要捕获组的初始完整状态,或要在稍后获取增量更改:Let's assume you are executing the following delta query - either to capture the initial full state of groups, or later on to get delta changes:

GET https://graph.microsoft.com/v1.0/groups/delta?$select=displayName,description,members
  1. Microsoft Graph 可能返回一个仅包含一个组对象的响应,其中 members@delta 属性中有一个大型成员列表:Microsoft Graph may return a response that contains just one group object, with a large list of members in the members@delta property:

第一页First page

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. 如果按照 nextLink 操作,可能会再次收到包含同一组对象的响应。When you follow the nextLink you may receive a response again containing the same group object. 将返回相同的属性值,但 members@delta 属性现在包含不同的用户列表。The same property values will be returned but the members@delta property now contains a different list of users.

第二页Second page

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. 最终,将以此方式返回整个成员列表,并且其他组将开始在响应中显示。Eventually, the entire member list will be returned in this fashion, and other groups will start showing up in the response.

建议使用以下最佳做法来正确处理此模式:We recommend the following best practices to correctly handle this pattern:

  • 始终按照 nextLink 操作,并在本地合并每个组的状态:当收到与同一个组相关的响应时,使用它们在应用程序中构建完整的成员身份列表。Always follow nextLink and locally merge each group's state: as you receive responses related to the same group, use them to build the full membership list in your application.
  • 最好不要假定响应的特定顺序。It is best not to assume a specific sequence of the responses. 假设同一组可以显示在 nextLink 序列的任意位置,并以合并逻辑进行处理。Assume that the same group could show up anywhere in the nextLink sequence and handle that in your merge logic.

另请参阅See also

Microsoft Graph delta 查询概述。Microsoft Graph delta query overview.