Разностный запрос в Microsoft Graph позволяет запрашивать добавления, удаления или обновления поддерживаемых ресурсов с помощью ряда разностных запросов. Для групп дельта-запрос позволяет обнаруживать изменения, не извлекая весь набор групп для сравнения изменений.
Клиенты, выполняющие синхронизацию групп с локальным хранилищем профилей, смогут использовать дельта-запрос как для первичной полной синхронизации, так и для добавочной синхронизации. Как правило, клиент выполняет начальную полную синхронизацию всех групп в клиенте, а затем периодически получает добавочные изменения в группы.
Отслеживание изменений в группах
Отслеживайте изменения пользователей с помощью одного или нескольких запросов GET с помощью функции delta. Запрос GET имеет следующие характеристики:
Функция delta , предопределенная URL-пути.
Маркер состояния (deltatoken или skiptoken) из предыдущего вызова разностной функции GET.
Чтобы отслеживать изменения в групповом ресурсе, сделайте запрос и включите дельта-функцию в виде сегмента URL-адреса.
Совет
/delta — это ярлык для полного имени /microsoft.graph.delta. Запросы, созданные пакетами SDK Для Microsoft Graph, используют полное имя.
Обратите внимание на следующие элементы:
Необязательный параметр $select включен в запрос, чтобы продемонстрировать, как параметры запроса автоматически включаются в последующие запросы. Если вы хотите использовать параметры запроса для управления объемом возвращаемых данных, необходимо включить их в первоначальный запрос.
На наличие изменений отслеживаются только свойства, включенные в $select . Если $select параметр не указан, все свойства объекта отслеживаются на наличие изменений.
Необязательный параметр запроса $select также используется, чтобы показать, как участников групп можно получать вместе с объектами групп. Эта возможность позволяет отслеживать изменения членства, например при добавлении или удалении пользователей из групп.
Исходный запрос не включает маркер состояния. Маркеры состояния используются в последующих запросах.
GET https://graph.microsoft.com/v1.0/groups/delta?$select=displayName,description,members
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Groups.Delta.GetAsDeltaGetResponseAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string []{ "displayName","description","members" };
});
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphgroups "github.com/microsoftgraph/msgraph-sdk-go/groups"
//other-imports
)
requestParameters := &graphgroups.GroupsDeltaRequestBuilderGetQueryParameters{
Select: [] string {"displayName","description","members"},
}
configuration := &graphgroups.GroupsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Groups().Delta().GetAsDeltaGetResponse(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
var result = graphClient.groups().delta().get(requestConfiguration -> {
requestConfiguration.queryParameters.select = new String []{"displayName", "description", "members"};
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.groups.delta.delta_request_builder import DeltaRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = DeltaRequestBuilder.DeltaRequestBuilderGetQueryParameters(
select = ["displayName","description","members"],
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.groups.delta.get(request_configuration = request_configuration)
В случае успешного выполнения этот метод возвращает код отклика 200 OK и объект коллекции group в тексте отклика. Если весь набор групп слишком велик, чтобы поместиться в один ответ, @odata.nextLink включается маркер состояния.
В этом примере возвращается URL-адрес @odata.nextLink. Это означает, что в текущем сеансе можно получить дополнительные страницы данных. Обратите внимание на в $skiptoken URL-адресе. Параметр $select из исходного запроса кодируется в URL-адресе @odata.nextLink.
Свойство members@delta входит в группу All Company и содержит двух текущих участников группы.
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"
}
]
}
Запрос nextLink
Во втором запросе используется ссылка @odata.nextLink из предыдущего запроса, содержащая маркер skiptoken. Обратите внимание, что параметр $select не виден, так как он закодирован и включен в маркер.
GET https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
// Note: The URI string parameter used with WithUrl() can be retrieved using the OdataNextLink or OdataDeltaLink property from a response object
var result = await graphClient.Groups.Delta.WithUrl("https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ").GetAsDeltaGetResponseAsync();
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphgroups "github.com/microsoftgraph/msgraph-sdk-go/groups"
//other-imports
)
requestSkiptoken := "pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ"
requestParameters := &graphgroups.GroupsDeltaRequestBuilderGetQueryParameters{
Skiptoken: &requestSkiptoken,
}
configuration := &graphgroups.GroupsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Groups().Delta().GetAsDeltaGetResponse(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.groups.delta.DeltaRequestBuilder deltaRequestBuilder = new com.microsoft.graph.groups.delta.DeltaRequestBuilder("https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ", graphClient.getRequestAdapter());
com.microsoft.graph.groups.delta.DeltaGetResponse result = deltaRequestBuilder.get();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.groups.delta.delta_request_builder import DeltaRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = DeltaRequestBuilder.DeltaRequestBuilderGetQueryParameters(
skiptoken = "pqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjvB7XnF_yllFsCrZJ",
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.groups.delta.get(request_configuration = request_configuration)
Ответ содержит ссылку @odata.nextLink с новым значением skiptoken, означающим, что доступны дополнительные изменения, которые были отслежены для групп.
@odata.nextLink Используйте URL-адрес в последующих запросах, пока @odata.deltaLink URL-адрес (в @odata.deltaLink параметре) не будет возвращен в окончательном ответе, даже если значение является пустым массивом.
GET https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=ppqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
// Note: The URI string parameter used with WithUrl() can be retrieved using the OdataNextLink or OdataDeltaLink property from a response object
var result = await graphClient.Groups.Delta.WithUrl("https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=ppqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7").GetAsDeltaGetResponseAsync();
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphgroups "github.com/microsoftgraph/msgraph-sdk-go/groups"
//other-imports
)
requestSkiptoken := "ppqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7"
requestParameters := &graphgroups.GroupsDeltaRequestBuilderGetQueryParameters{
Skiptoken: &requestSkiptoken,
}
configuration := &graphgroups.GroupsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Groups().Delta().GetAsDeltaGetResponse(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.groups.delta.DeltaRequestBuilder deltaRequestBuilder = new com.microsoft.graph.groups.delta.DeltaRequestBuilder("https://graph.microsoft.com/v1.0/groups/delta?$skiptoken=ppqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7", graphClient.getRequestAdapter());
com.microsoft.graph.groups.delta.DeltaGetResponse result = deltaRequestBuilder.get();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.groups.delta.delta_request_builder import DeltaRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = DeltaRequestBuilder.DeltaRequestBuilderGetQueryParameters(
skiptoken = "ppqwSUjGYvb3jQpbwVAwEL7yuI3dU1LecfkkfLPtnIjtQ5LOhVoS7qQG_wdVCHHlbQpga7",
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.groups.delta.get(request_configuration = request_configuration)
Если возвращается URL-адрес @odata.deltaLink, это означает, что больше нет данных о текущем состоянии объектов группы. В последующих запросах приложение использует URL-адрес @odata.deltaLink, чтобы узнавать о других изменениях групп. Сохраните маркер deltatoken и используйте его в URL-адресе последующего запроса, чтобы находить другие изменения в группах.
@odata.deltaLink Используя из последнего ответа, вы получаете изменения (добавления, удаления или обновления) в группах с момента последнего запроса. К таким изменениям относятся:
создание объектов групп;
удаление объектов групп;
Группировать объекты, для которых изменено отслеживаемое свойство (например, обновлено displayName).
Группирование объектов, для которых были добавлены или удалены объекты-члены.
GET https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
// Note: The URI string parameter used with WithUrl() can be retrieved using the OdataNextLink or OdataDeltaLink property from a response object
var result = await graphClient.Groups.Delta.WithUrl("https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw").GetAsDeltaGetResponseAsync();
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphgroups "github.com/microsoftgraph/msgraph-sdk-go/groups"
//other-imports
)
requestDeltatoken := "sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw"
requestParameters := &graphgroups.GroupsDeltaRequestBuilderGetQueryParameters{
Deltatoken: &requestDeltatoken,
}
configuration := &graphgroups.GroupsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Groups().Delta().GetAsDeltaGetResponse(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.groups.delta.DeltaRequestBuilder deltaRequestBuilder = new com.microsoft.graph.groups.delta.DeltaRequestBuilder("https://graph.microsoft.com/v1.0/groups/delta?$deltatoken=sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw", graphClient.getRequestAdapter());
com.microsoft.graph.groups.delta.DeltaGetResponse result = deltaRequestBuilder.get();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.groups.delta.delta_request_builder import DeltaRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = DeltaRequestBuilder.DeltaRequestBuilderGetQueryParameters(
deltatoken = "sZwAFZibx-LQOdZIo1hHhmmDhHzCY0Hs6snoIHJCSIfCHdqKdWNZ2VX3kErpyna9GygROwBk-rqWWMFxJC3pw",
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.groups.delta.get(request_configuration = request_configuration)
Если изменений нет, @odata.deltaLink возвращается без результатов — свойство value является пустым массивом. Обязательно замените предыдущую ссылку в приложении для использования в последующих запросах.
При наличии изменений включается коллекция измененных групп. Отклик также содержит ссылку @odata.nextLink (если требуется получить несколько страниц) или @odata.deltaLink. Реализуйте такой же порядок перехода по ссылкам @odata.nextLink, сохраняя заключительную ссылку @odata.deltaLink для последующих вызовов.
Примечание.
Этот запрос может иметь задержки репликации для недавно созданных, обновленных или удаленных групп. Повторите @odata.nextLink или @odata.deltaLink через некоторое время, чтобы получить последние изменения.
Некоторые моменты, которые следует отметить в примере ответа:
Объекты возвращаются с тем же набором свойств, который изначально указывался с помощью параметра запроса $select.
Включаются как измененные, так и неизменяемые свойства: свойство description имеет новое значение, а свойство displayName не изменилось.
members@delta содержит следующие изменения членства в группе.
Пользователь с идентификатором 632f6bb2-3ec8-4c1f-9073-0027a8c6859 был удален из группы, удалив его членство, как описано в свойстве @removed . Однако разностная функция не обнаруживает члены, которые удаляются из группы путем удаления объекта-члена.
Второй пользователь с идентификатором 37de1ae3-408f-4702-8636-20824abda004 был добавлен в группу.
Объект группы может содержать заметку @removed в следующих сценариях:
При удалении группы (группы Microsoft 365) элемент содержит заметку: @removed со значением "reason": "changed".
Заметок о создании или восстановлении группы не существует.
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 параметр явно указан. Для групп с большим количеством участников возможно, что все участники не смогут поместиться в один ответ. Реализуйте следующий шаблон в таких случаях.
Примечание.
Этот шаблон применяется как к первоначальному получению состояния группы, так и к последующим вызовам для получения разностных изменений.
Предположим, что выполняется следующий разностный запрос (либо для регистрации полного исходного состояния групп, либо для получения изменений):
GET https://graph.microsoft.com/v1.0/groups/delta?$select=displayName,description,members
// Code snippets are only available for the latest version. Current version is 5.x
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Groups.Delta.GetAsDeltaGetResponseAsync((requestConfiguration) =>
{
requestConfiguration.QueryParameters.Select = new string []{ "displayName","description","members" };
});
// Code snippets are only available for the latest major version. Current major version is $v1.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-sdk-go"
graphgroups "github.com/microsoftgraph/msgraph-sdk-go/groups"
//other-imports
)
requestParameters := &graphgroups.GroupsDeltaRequestBuilderGetQueryParameters{
Select: [] string {"displayName","description","members"},
}
configuration := &graphgroups.GroupsDeltaRequestBuilderGetRequestConfiguration{
QueryParameters: requestParameters,
}
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
delta, err := graphClient.Groups().Delta().GetAsDeltaGetResponse(context.Background(), configuration)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
var result = graphClient.groups().delta().get(requestConfiguration -> {
requestConfiguration.queryParameters.select = new String []{"displayName", "description", "members"};
});
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph import GraphServiceClient
from msgraph.generated.groups.delta.delta_request_builder import DeltaRequestBuilder
from kiota_abstractions.base_request_configuration import RequestConfiguration
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
query_params = DeltaRequestBuilder.DeltaRequestBuilderGetQueryParameters(
select = ["displayName","description","members"],
)
request_configuration = RequestConfiguration(
query_parameters = query_params,
)
result = await graph_client.groups.delta.get(request_configuration = request_configuration)
Microsoft Graph может возвращать ответ, содержащий только один объект группы с большим списком членов в свойстве 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...>
]
}
При выполнении @odata.nextLinkдействия может появиться ответ, содержащий тот же объект группы. Возвращаются те же значения свойств, 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": "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...>
]
}
В конечном итоге весь список участников возвращается таким образом, и другие группы начинают отображаться в ответе.
Для корректной реализации этого порядка следуйте приведенным ниже рекомендациям.
Всегда переходите по ссылке @odata.nextLink и локально выполняйте объединение для состояния каждой группы. По мере получения откликов для одной и той же группы составляйте полный список членов в приложении.
Не предполагайте определенную последовательность ответов. Предполагайте, что одна и та же группа может встречаться в любом месте последовательности @odata.nextLink, и обрабатывайте этот случай в логике объединения.