Объединение нескольких HTTP-запросов с помощью пакетной обработки JSON
Пакетная обработка JSON позволяет клиентам объединять несколько запросов в один объект JSON и один вызов HTTP, уменьшая циклы сетевых циклов и повышая эффективность. Microsoft Graph поддерживает пакетную обработку до 20 запросов в объект JSON.
В этой статье мы рассмотрим основы пакетной обработки JSON, как она работает и как ее можно использовать для оптимизации приложений.
Примечание.
Microsoft Graph реализует $batch
сегмент пути URL-адреса OData для поддержки пакетной обработки JSON.
Пример сценария
Рассмотрим клиента, который хочет создать представление следующих несвязанных данных:
- Изображение, хранящееся в OneDrive
- Список задач Планировщика
- Календарь группы
Объединение трех этих запросов в один может значительно снизить задержку в сети, ускорив работу приложения.
Создание пакетного запроса
Чтобы создать пакетный запрос, выполните приведенные далее действия.
Укажите метод HTTP запроса как POST.
Укажите конечную точку URL-адреса, направленную
v1.0
на версию Илиbeta
Microsoft Graph, и добавьте$batch
сегмент к URL-адресу. То есть .https://graph.microsoft.com/v1.0/$batch
Определите текст пакетного запроса следующим образом:
- Текст пакетного запроса JSON состоит из одного объекта JSON с одним обязательным свойством: requests. Это свойство представляет собой коллекцию отдельных запросов.
- Для каждого отдельного запроса можно передать следующие свойства.
Свойство Описание id Обязательно. Строка. Значение корреляции для связывания отдельных ответов с запросами. Это значение позволяет серверу обрабатывать запросы в пакете в наиболее эффективном порядке. Без учета регистра. Должен быть уникальным в пакете, в противном случае пакетный запрос завершается ошибкой 400
с кодом ошибки.метод Обязательный аргумент. Метод HTTP, поддерживаемый для запроса, указанного в URL-адресе. url Обязательный аргумент. Относительный URL-адрес ресурса для отдельного запроса. Таким образом, если абсолютный URL-адрес выглядит так: https://graph.microsoft.com/v1.0/users
, то этот URL-адрес выглядит так:/users
.заголовки Не является обязательным, но требуется, когда указан элементbody. Объект JSON с парой ключей и значений для заголовков. Например, если требуется заголовок ConsistencyLevel , это свойство представляется как "headers": {"ConsistencyLevel": "eventual"}
. Если предоставлен элемент body, должен быть включен заголовок Content-Type.body Необязательно. Может быть объектом JSON или значением в кодировке BASE64 URL, например, если текст является изображением. Когда элемент body включен в запрос, объект headers должен содержать значение для свойства 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 называется responses, а не requests.
- Порядок отображения ответов и запросов может отличаться. Свойство id можно использовать для корреляции отдельных запросов и ответов.
- Вместо метода и URL-адреса отдельные ответы имеют свойство 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"
}
]
}
}
]
}
Объяснение отдельных ответов в примере пакетного ответа
- Запросы 1 и 5 выполнены успешно, как показано в коде
200
состояния. - Запросы 2 и 3 завершились сбоем
403
с кодом состояния, так как у вызывающего не было необходимых разрешений. - Сбой
405
запроса 4 с кодом состояния, так как конечная точка, указанная в свойстве URL-адреса запроса, в настоящее время находится только вbeta
, но URL-адрес запроса предназначен дляv1.0
конечной точки Microsoft Graph. Хотя целевой URL-адрес не требует текста запроса, по-прежнему необходимо указать заголовки и пареметры текста , где пустой объект может быть только текстом .
Выстраивание последовательности запросов с помощью свойства dependsOn
Запросы в пакете, выполняемые в указанном порядке, можно указать с помощью свойства dependsOn . Это свойство представляет собой массив строк, который ссылается на идентификатор другого отдельного запроса. Например, в следующем запросе клиент указывает, что запросы должны выполняться в запросе порядка 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
(ошибка зависимости).
Совет
Пакет должен быть полностью последовательным или полностью параллельным.
Обход ограничения на длину URL-адреса с помощью пакетной обработки
Другой вариант использования пакетной обработки JSON — обход ограничений по длине URL-адресов. В случаях, когда предложение фильтра является сложным, длина URL-адреса может превышать ограничения, встроенные в браузеры или другие HTTP-клиенты. Пакетную обработку JSON можно использовать в качестве обходного решения для выполнения этих запросов, так как длинный URL-адрес просто становится частью полезных данных запроса.
Ограничения размера пакетов
- В настоящее время в пакетный запрос JSON можно включить не более 20 отдельных запросов.
- В зависимости от API- интерфейсов, входящих в пакетный запрос, базовые службы накладывают собственные ограничения регулирования , которые влияют на приложения, использующие Microsoft Graph для доступа к ним.
- Запросы в пакете оцениваются отдельно в соответствии с применимыми ограничениями регулирования, и если какой-либо запрос превышает эти ограничения, он завершается ошибкой с состоянием
429
.
Дополнительные сведения см в статье Регулирование и пакетная обработка.
Известные проблемы
Список текущих ограничений, связанных с пакетной обработкой, см. в разделе Известные проблемы.