Microsoft Graph Sdk を使用して要求をバッチ処理するUse the Microsoft Graph SDKs to batch requests

バッチ処理は、複数の要求を1つの HTTP 要求に結合する方法です。Batching is a way of combining multiple requests into a single HTTP request. 要求は、POST 経由で\$batchエンドポイントに送信される1つの JSON ペイロードで組み合わされます。The requests are combined in a single JSON payload, which is sent via POST to the \$batch endpoint. Microsoft Graph Sdk には、バッチペイロードを作成し、バッチ応答ペイロードを解析する方法を簡素化するためのクラスのセットが用意されています。Microsoft Graph SDKs have a set of classes to simplify how you create batch payloads and parse batch response payloads.

重要

Microsoft Graph の JSON バッチに関する現在の制限については、「既知の問題」を参照してください。For current limitations with JSON batching in Microsoft Graph, see Known Issues.

バッチ要求を作成するCreate a batch request

Microsoft Graph Sdk には、バッチ要求と応答を処理する3つのクラスが用意されています。The Microsoft Graph SDKs provide three classes to work with batch requests and responses.

  • Batchrequeststep -バッチ内の1つの要求GET /me(など) を表します。BatchRequestStep - Represents a single request (such as GET /me) within a batch. これにより、要求に一意の識別子を割り当て、要求間の依存関係を指定できるようになります。It enables assigning a unique identifier to the request and specifying dependencies between requests.
  • Batchrequestcontent -バッチ要求のペイロードを簡単に作成できます。BatchRequestContent - Simplifies creating the batch request payload. 複数のBatchrequeststepオブジェクトが含まれています。It contains multiple BatchRequestStep objects.
  • Batchresponse ・テント-バッチ要求からの応答の解析を簡素化します。BatchResponseContent - Simplifies parsing the response from a batch request. これは、すべての応答を取得し、ID で特定の応答を取得し、 @odata.nextLinkプロパティが存在する場合はプロパティを取得する機能を提供します。It provides the ability to get all responses, get a specific response by ID, and get the @odata.nextLink property if present.

単純なバッチ処理の例Simple batching example

この例では、互いに依存しないバッチで複数の要求を送信する方法を示します。This example shows how to send multiple requests in a batch that are not dependent on each other. 要求は、サービスによって任意の順序で実行できます。The requests can be run by the service in any order. この例では、ユーザーを取得し、現在の日付のユーザーの予定表ビューを取得します。This example gets the user and gets the user's calendar view for the current day.

// Use the request builder to generate a regular
// request to /me
var userRequest = graphClient.Me.Request();

var today = DateTime.Now.Date;
var start = today.ToString("yyyy-MM-ddTHH:mm:ssK");
var end = today.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ssK");

var queryOptions = new List<QueryOption>
{
    new QueryOption("startDateTime", start),
    new QueryOption("endDateTime", end)
};

// Use the request builder to generate a regular
// request to /me/calendarview?startDateTime="start"&endDateTime="end"
var eventsRequest = graphClient.Me.CalendarView.Request(queryOptions);

// Build the batch
var batchRequestContent = new BatchRequestContent();

// Using AddBatchRequestStep adds each request as a step
// with no specified order of execution
var userRequestId = batchRequestContent.AddBatchRequestStep(userRequest);
var eventsRequestId = batchRequestContent.AddBatchRequestStep(eventsRequest);

var returnedResponse = await graphClient.Batch.Request().PostAsync(batchRequestContent);

// De-serialize response based on known return type
try
{
    var user = await returnedResponse
        .GetResponseByIdAsync<User>(userRequestId);
    Console.WriteLine($"Hello {user.DisplayName}!");
}
catch (ServiceException ex)
{
    Console.WriteLine($"Get user failed: {ex.Error.Message}");
}

// For collections, must use the *CollectionResponse class to deserialize
// The .Value property will contain the *CollectionPage type that the Graph client
// returns from GetAsync().
try
{
    var events = await returnedResponse
        .GetResponseByIdAsync<UserCalendarViewCollectionResponse>(eventsRequestId);
    Console.WriteLine($"You have {events.Value.CurrentPage.Count} events on your calendar today.");
}
catch (ServiceException ex)
{
    Console.WriteLine($"Get calendar view failed: {ex.Error.Message}");
}

依存する要求があるバッチBatches with dependent requests

この例では、相互に依存する複数の要求をバッチで送信する方法を示します。This example shows how to send multiple requests in a batch that are dependent on each other. 要求は、依存関係によって指定された順序でサービスによって実行されます。The requests will be run by the service in the order specified by the dependencies. この例では、ユーザーの予定表に現在の日の開始時刻を含むイベントを追加し、現在の日付のユーザーの予定表ビューを取得します。This example adds an event with a start time during the current day to the user's calendar and gets the user's calendar view for the current day. 返された予定表レビューに新しいイベントが含まれていることを確認するには、予定表ビューの要求が、新しいイベントを追加する要求に応じて構成されている必要があります。To make sure that the calendar review returned includes the new event created, the request for the calendar view is configured as dependent on the request to add the new event. これにより、add イベント要求が最初に実行されるようになります。This ensures that the add event request will execute first.

注意

イベントの追加要求が失敗した場合、予定表ビューの取得要求424 Failed Dependencyは失敗し、エラーが発生します。If the add event request fails, the get calendar view request will fail with a 424 Failed Dependency error.

var today = DateTime.Now.Date;

var newEvent = new Event
{
    Subject = "File end-of-day report",
    Start = new DateTimeTimeZone
    {
        // 5:00 PM
        DateTime = today.AddHours(17).ToString("yyyy-MM-ddTHH:mm:ss"),
        TimeZone = TimeZoneInfo.Local.StandardName
    },
    End = new DateTimeTimeZone
    {
        // 5:30 PM
        DateTime = today.AddHours(17).AddMinutes(30).ToString("yyyy-MM-ddTHH:mm:ss"),
        TimeZone = TimeZoneInfo.Local.StandardName
    }
};

// POST requests are handled a bit differently
// The SDK request builders generate GET requests, so
// you must get the HttpRequestMessage and convert to a POST
var jsonEvent = graphClient.HttpProvider.Serializer.SerializeAsJsonContent(newEvent);

var addEventRequest = graphClient.Me.Events.Request().GetHttpRequestMessage();
addEventRequest.Method = HttpMethod.Post;
addEventRequest.Content = jsonEvent;

var start = today.ToString("yyyy-MM-ddTHH:mm:ssK");
var end = today.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ssK");

var queryOptions = new List<QueryOption>
{
    new QueryOption("startDateTime", start),
    new QueryOption("endDateTime", end)
};

// Use the request builder to generate a regular
// request to /me/calendarview?startDateTime="start"&endDateTime="end"
var calendarViewRequest = graphClient.Me.CalendarView.Request(queryOptions);

// Build the batch
var batchRequestContent = new BatchRequestContent();

// Force the requests to execute in order, so that the request for
// today's events will include the new event created.

// First request, no dependency
var addEventRequestId = batchRequestContent.AddBatchRequestStep(addEventRequest);

// Second request, depends on addEventRequestId
var eventsRequestId = Guid.NewGuid().ToString();
batchRequestContent.AddBatchRequestStep(new BatchRequestStep(
    eventsRequestId,
    calendarViewRequest.GetHttpRequestMessage(),
    new List<string> { addEventRequestId }
));

var returnedResponse = await graphClient.Batch.Request().PostAsync(batchRequestContent);

// De-serialize response based on known return type
try
{
    var createdEvent = await returnedResponse
        .GetResponseByIdAsync<Event>(addEventRequestId);
    Console.WriteLine($"New event created with ID: {createdEvent.Id}");
}
catch (ServiceException ex)
{
    Console.WriteLine($"Add event failed: {ex.Error.Message}");
}

// For collections, must use the *CollectionResponse class to deserialize
// The .Value property will contain the *CollectionPage type that the Graph client
// returns from GetAsync().
try
{
    var events = await returnedResponse
        .GetResponseByIdAsync<UserCalendarViewCollectionResponse>(eventsRequestId);
    Console.WriteLine($"You have {events.Value.CurrentPage.Count} events on your calendar today.");
}
catch (ServiceException ex)
{
    Console.WriteLine($"Get calendar view failed: {ex.Error.Message}");
}