Verwenden der Microsoft Graph SDKs zum Batchen von Anforderungen
Artikel
Batchverarbeitung ist eine Möglichkeit, mehrere Anforderungen in einer einzelnen HTTP-Anforderung zu kombinieren. Die Anforderungen werden in einer einzelnen JSON-Nutzlast kombiniert, die über POST an den \$batch Endpunkt gesendet wird. Microsoft Graph SDKs verfügen über eine Reihe von Klassen, um die Erstellung von Batchnutzlasten und das Analysieren von Batchantwortnutzlasten zu vereinfachen.
Wichtig
Aktuelle Einschränkungen bei der JSON-Batchverarbeitung in Microsoft Graph finden Sie unter Bekannte Probleme.
Erstellen einer Batchanforderung
Die Microsoft Graph SDKs bieten drei Klassen für die Arbeit mit Batchanforderungen und -antworten.
BatchRequestStep : Stellt eine einzelne Anforderung (z GET /me. B. ) innerhalb eines Batches dar. Es ermöglicht das Zuweisen eines eindeutigen Bezeichners zur Anforderung und das Angeben von Abhängigkeiten zwischen Anforderungen.
BatchRequestContent : Vereinfacht das Erstellen der Batchanforderungsnutzlast. Sie enthält mehrere BatchRequestStep-Objekte .
BatchResponseContent : Vereinfacht die Analyse der Antwort aus einer Batchanforderung. Es ermöglicht Ihnen, alle Antworten abzurufen, eine bestimmte Antwort nach ID abzurufen und die @odata.nextLink Eigenschaft abzurufen, falls vorhanden.
Automatische Batchverarbeitung für Anforderungsgrenzwerte
Das Microsoft Graph SDK verarbeitet automatisch Batchverarbeitungsanforderungen in Bezug auf den Grenzwert von 20 Anforderungen pro Batch. Dies bedeutet, dass das SDK die Anforderungen im Hintergrund in separate Batches aufteilt, wenn Ihr Code diesen Grenzwert überschreitet. Dadurch wird sichergestellt, dass jeder Batch die Einschränkung erfüllt. Sie müssen keine Logik mehr manuell implementieren, um dieses Batchverarbeitungslimit zu behandeln, wodurch Ihr Code übersichtlicher und einfacher zu verwalten ist.
Einfaches Batchverarbeitungsbeispiel
In diesem Beispiel wird gezeigt, wie mehrere Anforderungen in einem Batch gesendet werden, die nicht voneinander abhängig sind. Der Dienst kann die Anforderungen in beliebiger Reihenfolge ausführen. In diesem Beispiel wird der Benutzer und die Kalenderansicht des Benutzers für den aktuellen Tag abgerufen.
// 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}");
}
// Use the request builder to generate a regular
// request to /me
meRequest, err := graphClient.Me().
ToGetRequestInformation(context.Background(), nil)
if err != nil {
log.Fatalf("Error creating GET /me request: %v\n", err)
}
now := time.Now()
nowMidnight := time.Date(now.Year(), now.Month(), now.Day(),
0, 0, 0, 0, time.Local)
viewStart := nowMidnight.UTC().Format(time.RFC3339)
viewEnd := nowMidnight.AddDate(0, 0, 1).UTC().Format(time.RFC3339)
query := users.ItemCalendarViewRequestBuilderGetQueryParameters{
StartDateTime: &viewStart,
EndDateTime: &viewEnd,
Select: []string{"subject", "id"},
}
// Use the request builder to generate a request
// to /me/calendarView?startDateTime="start"&endDateTime="end"
eventsRequest, err := graphClient.Me().
CalendarView().
ToGetRequestInformation(context.Background(),
&users.ItemCalendarViewRequestBuilderGetRequestConfiguration{
QueryParameters: &query,
})
if err != nil {
log.Fatalf("Error creating GET /me/calendarView request: %v\n", err)
}
// Build the batch
batch := graphcore.NewBatchRequest(graphClient.GetAdapter())
// Using AddBatchRequestStep adds each request as a step
// with no specified order of execution
meRequestItem, err := batch.AddBatchRequestStep(*meRequest)
if err != nil {
log.Fatalf("Error adding GET /me request to batch: %v\n", err)
}
eventsRequestItem, err := batch.AddBatchRequestStep(*eventsRequest)
if err != nil {
log.Fatalf("Error adding GET /me/calendarView request to batch: %v\n", err)
}
batchResponse, err := batch.Send(context.Background(), graphClient.GetAdapter())
if err != nil {
log.Fatalf("Error sending batch: %v\n", err)
}
// De-serialize response based on known return type
user, err := graphcore.GetBatchResponseById[models.Userable](
batchResponse, *meRequestItem.GetId(), models.CreateUserFromDiscriminatorValue)
if err != nil {
log.Fatalf("Error reading GET /me response: %v\n", err)
}
fmt.Printf("Hello %s\n", *(user.GetDisplayName()))
// For collections, must use the *CollectionResponseable class to deserialize
events, err := graphcore.GetBatchResponseById[models.EventCollectionResponseable](
batchResponse, *eventsRequestItem.GetId(),
models.CreateEventCollectionResponseFromDiscriminatorValue)
if err != nil {
log.Fatalf("Error reading GET /me/calendarView response: %v\n", err)
}
fmt.Printf("You have %d events on your calendar today\n", len(events.GetValue()))
// Create the batch request content with the steps
final BatchRequestContent batchRequestContent = new BatchRequestContent(
graphClient);
// Use the Graph client to generate the requestInformation object for GET /me
final RequestInformation meRequestInformation = graphClient.me()
.toGetRequestInformation();
final ZoneOffset localTimeZone = OffsetDateTime.now().getOffset();
final OffsetDateTime today = OffsetDateTime.of(LocalDate.now(),
LocalTime.MIDNIGHT, localTimeZone);
final OffsetDateTime tomorrow = today.plusDays(1);
// Use the Graph client to generate the requestInformation for
// GET /me/calendarView?startDateTime="start"&endDateTime="end"
RequestInformation calenderViewRequestInformation = graphClient.me()
.calendarView().toGetRequestInformation(requestConfiguration -> {
requestConfiguration.queryParameters.startDateTime = today.toString();
requestConfiguration.queryParameters.endDateTime = tomorrow.toString();
});
// Add the requestInformation objects to the batch request content
final String meRequestId = batchRequestContent
.addBatchRequestStep(meRequestInformation);
final String calendarViewRequestStepId = batchRequestContent
.addBatchRequestStep(calenderViewRequestInformation);
// Send the batch request content to the /$batch endpoint
final BatchResponseContent batchResponseContent = Objects.requireNonNull(
graphClient.getBatchRequestBuilder().post(batchRequestContent, null));
// Get the user response using the id assigned to the request
final User me = batchResponseContent.getResponseById(meRequestId,
User::createFromDiscriminatorValue);
System.out.println(String.format("Hello %s!", me.getDisplayName()));
// Get the calendar view response by id
final EventCollectionResponse eventsResponse = Objects.requireNonNull(
batchResponseContent.getResponseById(calendarViewRequestStepId,
EventCollectionResponse::createFromDiscriminatorValue));
System.out.println(String.format("You have %d events on your calendar today",
Objects.requireNonNull(eventsResponse.getValue()).size()));
// Use the request builder to generate a GET
// request to /me
$userRequest = $graphClient->me()->toGetRequestInformation();
$timeZone = new \DateTimeZone('America/New_York');
$today = new \DateTimeImmutable('today midnight', $timeZone);
$tomorrow = new \DateTimeImmutable('tomorrow midnight', $timeZone);
// Use the request builder to generate a GET
// request to /me/calendarView?startDateTime="start"&endDateTime="end"
$query = new CalendarViewRequestBuilderGetQueryParameters(
startDateTime: $today->format(\DateTime::ATOM),
endDateTime: $tomorrow->format(\DateTime::ATOM));
$config = new CalendarViewRequestBuilderGetRequestConfiguration(queryParameters: $query);
$eventsRequest = $graphClient->me()->calendarView()->toGetRequestInformation($config);
// Build the batch
$userRequestItem = new BatchRequestItem($userRequest);
$eventsRequestItem = new BatchRequestItem($eventsRequest);
$batchRequestContent = new BatchRequestContent([$userRequestItem, $eventsRequestItem]);
// Create a batch request builder to send the batched requests
$batchRequestBuilder = new BatchRequestBuilder($graphClient->getRequestAdapter());
/** @var BatchResponseContent $batchResponse */
$batchResponse = $batchRequestBuilder->postAsync($batchRequestContent)->wait();
// De-serialize the responses
$user = $batchResponse->getResponseBody($userRequestItem->getId(), Models\User::class);
print('Hello '.$user->getDisplayName().'!'.PHP_EOL);
// For collections, must use the *CollectionResponse class to deserialize
// getValue will return an array of items
$events = $batchResponse->getResponseBody($eventsRequestItem->getId(), Models\EventCollectionResponse::class);
print('You have '.count($events->getValue()).' events on your calendar today'.PHP_EOL);
// Create a batch request step to GET /me
// Request is from fetch polyfill, i.e. node-fetch
const userRequestStep: BatchRequestStep = {
id: '1',
request: new Request('https://graph.microsoft.com/me', {
method: 'GET',
}),
};
// startOfToday and endOfToday from date-fns
const start = startOfToday().toISOString();
const end = endOfToday().toISOString();
// Create a batch request step to GET
// /me/calendarView?startDateTime="start"&endDateTime="end"
const calendarViewRequestStep: BatchRequestStep = {
id: '2',
request: new Request(
`https://graph.microsoft.com/me/calendarView?startDateTime=${start}&endDateTime=${end}`,
{
method: 'GET',
},
),
};
// Create the batch request content with the steps created
// above
const batchRequestContent = new BatchRequestContent([
userRequestStep,
calendarViewRequestStep,
]);
const content = await batchRequestContent.getContent();
// POST the batch request content to the /$batch endpoint
const batchResponse = await graphClient.api('/$batch').post(content);
// Create a BatchResponseContent object to parse the response
const batchResponseContent = new BatchResponseContent(batchResponse);
// Get the user response using the id assigned to the request
const userResponse = batchResponseContent.getResponseById('1');
// For a single entity, the JSON payload can be deserialized
// into the expected type
// Types supplied by @microsoft/microsoft-graph-types
if (userResponse.ok) {
const user: User = (await userResponse.json()) as User;
console.log(`Hello ${user.displayName}!`);
} else {
console.log(`Get user failed with status ${userResponse.status}`);
}
// Get the calendar view response by id
const calendarResponse = batchResponseContent.getResponseById('2');
// For a collection of entities, the "value" property of
// the JSON payload can be deserialized into an array of
// the expected type
if (calendarResponse.ok) {
const rawResponse = (await calendarResponse.json()) as PageCollection;
const events: Event[] = rawResponse.value;
console.log(`You have ${events.length} events on your calendar today.`);
} else {
console.log(
`Get calendar view failed with status ${calendarResponse.status}`,
);
}
Batches mit abhängigen Anforderungen
In diesem Beispiel wird gezeigt, wie mehrere Anforderungen in einem Batch gesendet werden, die voneinander abhängig sind. Der Dienst führt die Anforderung in der von den Abhängigkeiten angegebenen Reihenfolge aus. In diesem Beispiel wird dem Kalender des Benutzers ein Ereignis mit einer Startzeit während des aktuellen Tages hinzugefügt und die Kalenderansicht des Benutzers für den aktuellen Tag abgerufen. Um sicherzustellen, dass die zurückgegebene Kalenderüberprüfung das neu erstellte Ereignis enthält, wird die Anforderung für die Kalenderansicht als abhängig von der Anforderung zum Hinzufügen des neuen Ereignisses konfiguriert. Dadurch wird sichergestellt, dass die Ereignisanforderung zum Hinzufügen zuerst ausgeführt wird.
Hinweis
Wenn bei der Anforderung zum Hinzufügen von Ereignissen ein Fehler auftritt, schlägt die Anforderung zum Abrufen der Kalenderansicht mit einem 424 Failed Dependency Fehler fehl.
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}");
}
now := time.Now()
nowMidnight := time.Date(now.Year(), now.Month(), now.Day(),
0, 0, 0, 0, time.Local)
timeZone, _ := tzlocal.RuntimeTZ()
// 5:00 PM
startDateTime := nowMidnight.Add(time.Hour * 17)
// 5:30 PM
endDateTime := startDateTime.Add(time.Minute * 30)
graphDateTimeFormat := "2006-01-02T15:04:05"
// Create event
newEvent := models.NewEvent()
subject := "File end-of-day report"
newEvent.SetSubject(&subject)
start := models.NewDateTimeTimeZone()
startString := startDateTime.Format(graphDateTimeFormat)
start.SetDateTime(&startString)
start.SetTimeZone(&timeZone)
newEvent.SetStart(start)
end := models.NewDateTimeTimeZone()
endString := endDateTime.Format(graphDateTimeFormat)
end.SetDateTime(&endString)
end.SetTimeZone(&timeZone)
newEvent.SetEnd(end)
addEventRequest, err := graphClient.Me().
Events().
ToPostRequestInformation(context.Background(), newEvent, nil)
if err != nil {
log.Fatalf("Error creating POST /me/events request: %v\n", err)
}
viewStart := nowMidnight.UTC().Format(time.RFC3339)
viewEnd := nowMidnight.AddDate(0, 0, 1).UTC().Format(time.RFC3339)
query := users.ItemCalendarViewRequestBuilderGetQueryParameters{
StartDateTime: &viewStart,
EndDateTime: &viewEnd,
Select: []string{"subject", "id"},
}
// Use the request builder to generate a request
// to /me/calendarView?startDateTime="start"&endDateTime="end"
eventsRequest, err := graphClient.Me().
CalendarView().
ToGetRequestInformation(context.Background(),
&users.ItemCalendarViewRequestBuilderGetRequestConfiguration{
QueryParameters: &query,
})
if err != nil {
log.Fatalf("Error creating GET /me/calendarView request: %v\n", err)
}
// Build the batch
batch := graphcore.NewBatchRequest(graphClient.GetAdapter())
// 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
addEventRequestItem, err := batch.AddBatchRequestStep(*addEventRequest)
if err != nil {
log.Fatalf("Error adding POST /me/events request to batch: %v\n", err)
}
// Second request, depends on addEventRequestId
eventsRequestItem, err := batch.AddBatchRequestStep(*eventsRequest)
if err != nil {
log.Fatalf("Error creating GET /me/calendarView request to batch: %v\n", err)
}
eventsRequestItem.DependsOnItem(addEventRequestItem)
batchResponse, err := batch.Send(context.Background(), graphClient.GetAdapter())
if err != nil {
log.Fatalf("Error sending batch: %v\n", err)
}
// De-serialize response based on known return type
event, err := graphcore.GetBatchResponseById[models.Eventable](
batchResponse, *addEventRequestItem.GetId(),
models.CreateEventFromDiscriminatorValue)
if err != nil {
log.Fatalf("Error reading POST /me/events response: %v\n", err)
}
fmt.Printf("New event created with ID: %s\n", *(event.GetId()))
// For collections, must use the *CollectionResponseable class to deserialize
events, err := graphcore.GetBatchResponseById[models.EventCollectionResponseable](
batchResponse, *eventsRequestItem.GetId(),
models.CreateEventCollectionResponseFromDiscriminatorValue)
if err != nil {
log.Fatalf("Error reading GET /me/calendarView response: %v\n", err)
}
fmt.Printf("You have %d events on your calendar today\n", len(events.GetValue()))
// Create the batch request content with the steps
final BatchRequestContent batchRequestContent = new BatchRequestContent(
graphClient);
final ZoneOffset localTimeZone = OffsetDateTime.now().getOffset();
final OffsetDateTime today = OffsetDateTime.of(LocalDate.now(),
LocalTime.MIDNIGHT, localTimeZone);
final OffsetDateTime tomorrow = today.plusDays(1);
// Create a new event for today at 5:00 PM
final Event newEvent = new Event();
newEvent.setSubject("File end-of-day report");
// 5:00 PM
final DateTimeTimeZone start = new DateTimeTimeZone();
start.setDateTime(
today.plusHours(17).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
start.setTimeZone(ZoneOffset.systemDefault().getId());
newEvent.setStart(start);
// 5:30 PM
final DateTimeTimeZone end = new DateTimeTimeZone();
end.setDateTime(today.plusHours(17).plusMinutes(30)
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
end.setTimeZone(ZoneOffset.systemDefault().getId());
newEvent.setEnd(end);
// Use the Graph client to add the requestInformation for POST /me/events
RequestInformation postEventRequestInformation = graphClient.me().events()
.toPostRequestInformation(newEvent);
// Get the id assigned to the request
String postEventRequestId = batchRequestContent
.addBatchRequestStep(postEventRequestInformation);
// Use the Graph client to generate the requestInformation
// GET /me/calendarView?startDateTime="start"&endDateTime="end"
final RequestInformation calendarViewRequestInformation = graphClient.me()
.calendarView().toGetRequestInformation(requestConfiguration -> {
requestConfiguration.queryParameters.startDateTime = today.toString();
requestConfiguration.queryParameters.endDateTime = tomorrow.toString();
});
final String calendarViewRequestId = batchRequestContent
.addBatchRequestStep(calendarViewRequestInformation);
// Set the dependsOnId to 'postEventRequestId'
batchRequestContent.getBatchRequestSteps().get(calendarViewRequestId)
.addDependsOnId(postEventRequestId);
// Send the batch request content to the /$batch endpoint
final BatchResponseContent batchResponseContent = Objects.requireNonNull(
graphClient.getBatchRequestBuilder().post(batchRequestContent, null));
// Get the event response using the id assigned to the request
final Event postedEvent = batchResponseContent.getResponseById(postEventRequestId,
Event::createFromDiscriminatorValue);
System.out.println(String.format("New event created with ID: %s",
Objects.requireNonNull(postedEvent.getId())));
// Get the calendar view response by id
final EventCollectionResponse eventsResponse = Objects
.requireNonNull(batchResponseContent.getResponseById(calendarViewRequestId,
EventCollectionResponse::createFromDiscriminatorValue));
System.out.println(String.format("You have %d events on your calendar today",
Objects.requireNonNull(eventsResponse.getValue().size())));
$startTime = new \DateTimeImmutable('today 5PM');
$endTime = $startTime->add(new \DateInterval('PT30M'));
$newEvent = new Models\Event();
$newEvent->setSubject('File end-of-day report');
$start = new Models\DateTimeTimeZone();
$start->setDateTime($startTime->format('Y-m-d\TH:i:s'));
$start->setTimeZone('Eastern Standard Time');
$newEvent->setStart($start);
$end = new Models\DateTimeTimeZone();
$end->setDateTime($endTime->format('Y-m-d\TH:i:s'));
$end->setTimeZone('Eastern Standard Time');
$newEvent->setEnd($end);
// Use the request builder to generate a
// POST request to /me/events
$addEventRequest = $graphClient->me()->events()->toPostRequestInformation($newEvent);
$timeZone = new \DateTimeZone('America/New_York');
$today = new \DateTimeImmutable('today midnight', $timeZone);
$tomorrow = new \DateTimeImmutable('tomorrow midnight', $timeZone);
// Use the request builder to generate a GET
// request to /me/calendarView?startDateTime="start"&endDateTime="end"
$query = new CalendarViewRequestBuilderGetQueryParameters(
startDateTime: $today->format(\DateTime::ATOM),
endDateTime: $tomorrow->format(\DateTime::ATOM));
$config = new CalendarViewRequestBuilderGetRequestConfiguration(queryParameters: $query);
$eventsRequest = $graphClient->me()->calendarView()->toGetRequestInformation($config);
// Build the batch
// 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
$addEventRequestItem = new BatchRequestItem($addEventRequest);
// Second request, depends on addEventRequestItem
$eventsRequestItem = new BatchRequestItem($eventsRequest, dependsOn: [$addEventRequestItem]);
$batchRequestContent = new BatchRequestContent([$addEventRequestItem, $eventsRequestItem]);
// Create a batch request builder to send the batched requests
$batchRequestBuilder = new BatchRequestBuilder($graphClient->getRequestAdapter());
/** @var BatchResponseContent $batchResponse */
$batchResponse = $batchRequestBuilder->postAsync($batchRequestContent)->wait();
// De-serialize the responses
$createdEvent = $batchResponse->getResponseBody($addEventRequestItem->getId(), Models\Event::class);
print('New event created with ID: '.$createdEvent->getId().PHP_EOL);
// For collections, must use the *CollectionResponse class to deserialize
// getValue will return an array of items
$events = $batchResponse->getResponseBody($eventsRequestItem->getId(), Models\EventCollectionResponse::class);
print('You have '.count($events->getValue()).' events on your calendar today'.PHP_EOL);
// 5:00 PM today
// startOfToday, endOfToday, setHours, setMinutes, format from date-fns
const eventStart = setHours(startOfToday(), 17);
const eventEnd = setMinutes(eventStart, 30);
// Create a batch request step to add an event
const newEvent: Event = {
subject: 'File end-of-day report',
start: {
dateTime: format(eventStart, `yyyy-MM-dd'T'HH:mm:ss`),
timeZone: 'Pacific Standard Time',
},
end: {
// 5:30 PM
dateTime: format(eventEnd, `yyyy-MM-dd'T'HH:mm:ss`),
timeZone: 'Pacific Standard Time',
},
};
// Request is from fetch polyfill, i.e. node-fetch
const addEventRequestStep: BatchRequestStep = {
id: '1',
request: new Request('https://graph.microsoft.com/me/events', {
method: 'POST',
body: JSON.stringify(newEvent),
headers: {
'Content-Type': 'application/json',
},
}),
};
const start = startOfToday().toISOString();
const end = endOfToday().toISOString();
// Create a batch request step to GET
// /me/calendarView?startDateTime="start"&endDateTime="end"
const calendarViewRequestStep: BatchRequestStep = {
id: '2',
// This step will happen after step 1
dependsOn: ['1'],
request: new Request(
`https://graph.microsoft.com/me/calendarView?startDateTime=${start}&endDateTime=${end}`,
{
method: 'GET',
},
),
};
// Create the batch request content with the steps created
// above
const batchRequestContent = new BatchRequestContent([
addEventRequestStep,
calendarViewRequestStep,
]);
const content = await batchRequestContent.getContent();
// POST the batch request content to the /$batch endpoint
const batchResponse = await graphClient.api('/$batch').post(content);
// Create a BatchResponseContent object to parse the response
const batchResponseContent = new BatchResponseContent(batchResponse);
// Get the create event response by id
const newEventResponse = batchResponseContent.getResponseById('1');
if (newEventResponse.ok) {
const event: Event = (await newEventResponse.json()) as Event;
console.log(`New event created with ID: ${event.id}`);
} else {
console.log(`Create event failed with status ${newEventResponse.status}`);
}
// Get the calendar view response by id
const calendarResponse = batchResponseContent.getResponseById('2');
if (calendarResponse.ok) {
// For a collection of entities, the "value" property of
// the JSON payload can be deserialized into an array of
// the expected type
const rawResponse = (await calendarResponse.json()) as PageCollection;
const events: Event[] = rawResponse.value;
console.log(`You have ${events.length} events on your calendar today.`);
} else {
console.log(
`Get calendar view failed with status ${calendarResponse.status}`,
);
}