Работа с действиями, выполняющимися длительное время
Статья
В этой статье описывается, как работать с длительными действиями при использовании API Microsoft Graph. Для выполнения некоторых ответов API требуется неопределенное время. Вместо того чтобы ждать завершения действия перед возвратом ответа, Microsoft Graph может использовать шаблон длительных действий. Этот шаблон предоставляет приложению способ опроса на наличие обновлений состояния для длительного действия без запроса, ожидающего завершения действия.
Общий шаблон включает в себя следующие шаги:
Приложение запрашивает длительное действие через API. API принимает действие и возвращает ответ вместе с заголовком 202 AcceptedLocation URL-адреса API для получения отчетов о состоянии действий.
Приложение запрашивает URL-адрес отчета о состоянии действия и получает ответ asyncJobStatus о ходе выполнения длительного действия.
Длительное действие завершается.
Приложение снова запрашивает URL-адрес отчета о состоянии действия и получает ответ asyncJobStatus , показывающий завершение действия.
Предварительные условия
Те же разрешения , необходимые для выполнения длительного действия, также требуются для запроса состояния длительного действия.
Начальный запрос действия
В следующем примере используется метод driveitem: copy .
В этом сценарии приложение отправляет запрос на копирование папки, содержащей большой объем данных.
Выполнение этого запроса, скорее всего, займет несколько секунд, так как объем данных большой.
POST https://graph.microsoft.com/beta/me/drive/items/{folder-item-id}/copy
Content-Type: application/json
{
"parentReference": {
"path": "/drive/root:/Documents"
},
"name": "Copy of LargeFolder1"
}
// Code snippets are only available for the latest version. Current version is 5.x
// Dependencies
using Microsoft.Graph.Beta.Drives.Item.Items.Item.Copy;
using Microsoft.Graph.Beta.Models;
var requestBody = new CopyPostRequestBody
{
ParentReference = new ItemReference
{
Path = "/drive/root:/Documents",
},
Name = "Copy of LargeFolder1",
};
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=csharp
var result = await graphClient.Drives["{drive-id}"].Items["{driveItem-id}"].Copy.PostAsync(requestBody);
// Code snippets are only available for the latest major version. Current major version is $v0.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-beta-sdk-go"
graphdrives "github.com/microsoftgraph/msgraph-beta-sdk-go/drives"
graphmodels "github.com/microsoftgraph/msgraph-beta-sdk-go/models"
//other-imports
)
requestBody := graphdrives.NewCopyPostRequestBody()
parentReference := graphmodels.NewItemReference()
path := "/drive/root:/Documents"
parentReference.SetPath(&path)
requestBody.SetParentReference(parentReference)
name := "Copy of LargeFolder1"
requestBody.SetName(&name)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
copy, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Copy().Post(context.Background(), requestBody, nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
com.microsoft.graph.beta.drives.item.items.item.copy.CopyPostRequestBody copyPostRequestBody = new com.microsoft.graph.beta.drives.item.items.item.copy.CopyPostRequestBody();
ItemReference parentReference = new ItemReference();
parentReference.setPath("/drive/root:/Documents");
copyPostRequestBody.setParentReference(parentReference);
copyPostRequestBody.setName("Copy of LargeFolder1");
var result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").copy().post(copyPostRequestBody);
<?php
use Microsoft\Graph\Beta\GraphServiceClient;
use Microsoft\Graph\Beta\Generated\Drives\Item\Items\Item\Copy\CopyPostRequestBody;
use Microsoft\Graph\Beta\Generated\Models\ItemReference;
$graphServiceClient = new GraphServiceClient($tokenRequestContext, $scopes);
$requestBody = new CopyPostRequestBody();
$parentReference = new ItemReference();
$parentReference->setPath('/drive/root:/Documents');
$requestBody->setParentReference($parentReference);
$requestBody->setName('Copy of LargeFolder1');
$result = $graphServiceClient->drives()->byDriveId('drive-id')->items()->byDriveItemId('driveItem-id')->copy()->post($requestBody)->wait();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph_beta import GraphServiceClient
from msgraph_beta.generated.drives.item.items.item.copy.copy_post_request_body import CopyPostRequestBody
from msgraph_beta.generated.models.item_reference import ItemReference
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
request_body = CopyPostRequestBody(
parent_reference = ItemReference(
path = "/drive/root:/Documents",
),
name = "Copy of LargeFolder1",
)
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').copy.post(request_body)
Примечание: Возвращаемый URL-адрес расположения может не находиться в конечной точке API Microsoft Graph.
Во многих случаях этот шаг является завершением запроса, так как действие копирования завершается без каких-либо других действий из приложения.
Однако если приложению нужно отобразить состояние действия копирования или убедиться, что оно будет выполнено без ошибок, оно может сделать это с помощью URL-адреса монитора.
Получение отчета о состоянии с URL-адреса для отслеживания
Чтобы проверить состояние действия копирования, приложение отправляет запрос на URL-адрес, указанный в предыдущем отклике.
Примечание: Этот запрос не требует проверки подлинности, так как URL-адрес является краткосрочным и уникальным для исходного вызывающего объекта.
GET https://api.onedrive.com/monitor/4A3407B5-88FC-4504-8B21-0AABD3412717
Служба отвечает информацией о том, что длительное действие все еще выполняется.
Эти сведения можно использовать для обновления информации о ходе копирования для пользователя.
Приложение может продолжить опрашивать URL-адрес для отслеживания, чтобы получать обновленные сведения о ходе выполнения действия.
Получение отчета о выполнении действия с URL-адреса для отслеживания
Через несколько секунд операция копирования завершается.
На этот раз, когда приложение отправляет запрос к URL-адресу монитора, ответ представляет собой перенаправление на готовый результат действия.
GET https://api.onedrive.com/monitor/4A3407B5-88FC-4504-8B21-0AABD3412717
По завершении действия ответ от службы мониторинга возвращает идентификатор ресурса для результатов.
После завершения задания URL-адрес монитора возвращает идентификатор ресурса результата. В этом случае это новая копия исходного элемента.
В следующем примере показано, как обратиться к этому новому элементу с помощью идентификатора ресурса.
GET https://graph.microsoft.com/beta/me/drive/items/{item-id}
// 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.Drives["{drive-id}"].Items["{driveItem-id}"].GetAsync();
// Code snippets are only available for the latest major version. Current major version is $v0.*
// Dependencies
import (
"context"
msgraphsdk "github.com/microsoftgraph/msgraph-beta-sdk-go"
//other-imports
)
// To initialize your graphClient, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=go
items, err := graphClient.Drives().ByDriveId("drive-id").Items().ByDriveItemId("driveItem-id").Get(context.Background(), nil)
// Code snippets are only available for the latest version. Current version is 6.x
GraphServiceClient graphClient = new GraphServiceClient(requestAdapter);
DriveItem result = graphClient.drives().byDriveId("{drive-id}").items().byDriveItemId("{driveItem-id}").get();
# Code snippets are only available for the latest version. Current version is 1.x
from msgraph_beta import GraphServiceClient
# To initialize your graph_client, see https://learn.microsoft.com/en-us/graph/sdks/create-client?from=snippets&tabs=python
result = await graph_client.drives.by_drive_id('drive-id').items.by_drive_item_id('driveItem-id').get()