Partilhar via


Utilizar os SDKs do Microsoft Graph para pedidos em lote

A criação de batches é uma forma de combinar vários pedidos num único pedido HTTP. Os pedidos são combinados num único payload JSON, que é enviado através de POST para o \$batch ponto final. Os SDKs do Microsoft Graph têm um conjunto de classes para simplificar a forma como cria payloads em lote e analisa payloads de resposta em lote.

Importante

Para obter as limitações atuais com a criação de batches JSON no Microsoft Graph, veja Problemas Conhecidos.

Criar uma solicitação em lote

Os SDKs do Microsoft Graph fornecem três classes para trabalhar com pedidos e respostas em lote.

  • BatchRequestStep – representa um único pedido (como GET /me) dentro de um lote. Permite atribuir um identificador exclusivo ao pedido e especificar dependências entre pedidos.
  • BatchRequestContent – simplifica a criação do payload do pedido de lote. Contém vários objetos BatchRequestStep .
  • BatchResponseContent - Simplifica a análise da resposta a partir de um pedido de lote. Permite-lhe obter todas as respostas, obter uma resposta específica por ID e obter a @odata.nextLink propriedade, se estiver presente.

Criação automática de batches para limites de pedidos

O SDK do Microsoft Graph processa automaticamente pedidos de criação de batches no que diz respeito ao limite de 20 pedidos por lote. Isto significa que, se o código exceder este limite, o SDK divide os pedidos em lotes separados em segundo plano. Isto garante que cada lote está em conformidade com a limitação. Já não precisa de implementar manualmente a lógica para processar este limite de criação de lotes, o que torna o seu código mais limpo e fácil de gerir.

Exemplo de criação de batches simples

Este exemplo mostra como enviar vários pedidos num lote que não dependem uns dos outros. O serviço pode executar os pedidos por qualquer ordem. Este exemplo obtém o utilizador e obtém a vista de calendário do utilizador para o dia atual.

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

var today = DateTime.Now.Date;

// Use the request builder to generate a regular
// request to /me/calendarview?startDateTime="start"&endDateTime="end"
var eventsRequest = graphClient.Me.CalendarView
    .ToGetRequestInformation(requestConfiguration =>
        {
            requestConfiguration.QueryParameters.StartDateTime =
                today.ToString("yyyy-MM-ddTHH:mm:ssK");
            requestConfiguration.QueryParameters.EndDateTime =
                today.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ssK");
        });

// Build the batch
var batchRequestContent = new BatchRequestContentCollection(graphClient);

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

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

// De-serialize response based on known return type
try
{
    var user = await returnedResponse
        .GetResponseByIdAsync<User>(userRequestId);
    Console.WriteLine($"Hello {user.DisplayName}!");
}
catch (Exception ex)
{
    Console.WriteLine($"Get user failed: {ex.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<EventCollectionResponse>(eventsRequestId);
    Console.WriteLine(
        $"You have {events.Value?.Count} events on your calendar today.");
}
catch (Exception ex)
{
    Console.WriteLine($"Get calendar view failed: {ex.Message}");
}

Lotes com pedidos dependentes

Este exemplo mostra como enviar vários pedidos num lote que dependem uns dos outros. O serviço executa o pedido pela ordem especificada pelas dependências. Este exemplo adiciona um evento com uma hora de início durante o dia atual ao calendário do utilizador e obtém a vista de calendário do utilizador para o dia atual. Para se certificar de que a revisão do calendário devolvida inclui o novo evento criado, o pedido para a vista de calendário está configurado como dependente do pedido para adicionar o novo evento. Isto garante que o pedido de adição de eventos é executado primeiro.

Observação

Se o pedido de adição de eventos falhar, o pedido obter vista de calendário falhará com um 424 Failed Dependency erro.

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,
    },
};

// Use the request builder to generate a regular
// POST request to /me/events
var addEventRequest = graphClient.Me.Events
    .ToPostRequestInformation(newEvent);

// Use the request builder to generate a regular
// request to /me/calendarview?startDateTime="start"&endDateTime="end"
var calendarViewRequest = graphClient.Me.CalendarView.ToGetRequestInformation(
    requestConfiguration =>
    {
        requestConfiguration.QueryParameters.StartDateTime =
            today.ToString("yyyy-MM-ddTHH:mm:ssK");
        requestConfiguration.QueryParameters.EndDateTime =
            today.AddDays(1).ToString("yyyy-MM-ddTHH:mm:ssK");
    });

// Build the batch
var batchRequestContent = new BatchRequestContentCollection(graphClient);

// 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 = await batchRequestContent
    .AddBatchRequestStepAsync(addEventRequest);

// Second request, depends on addEventRequestId
var eventsRequestId = Guid.NewGuid().ToString();
var eventsRequestMessage = await graphClient.RequestAdapter
    .ConvertToNativeRequestAsync<HttpRequestMessage>(calendarViewRequest);
batchRequestContent.AddBatchRequestStep(new BatchRequestStep(
    eventsRequestId,
    eventsRequestMessage,
    [addEventRequestId]));

var returnedResponse = await graphClient.Batch.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 (Exception ex)
{
    Console.WriteLine($"Add event failed: {ex.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<EventCollectionResponse>(eventsRequestId);
    Console.WriteLine(
        $"You have {events.Value?.Count} events on your calendar today.");
}
catch (Exception ex)
{
    Console.WriteLine($"Get calendar view failed: {ex.Message}");
}