Página a través de una colección mediante los SDK de Microsoft Graph
Artículo
Por motivos de rendimiento, las colecciones de entidades a menudo se dividen en páginas y cada página se devuelve con una dirección URL a la página siguiente. La clase PageIterator simplifica el consumo de colecciones paginadas. PageIterator controla la enumeración de la página actual y la solicitud de páginas posteriores automáticamente.
Encabezados de solicitud
Si envía encabezados de solicitud adicionales en la solicitud inicial, esos encabezados no se incluyen de forma predeterminada en las solicitudes de página posteriores. Si es necesario enviar esos encabezados en solicitudes posteriores, debe establecerlos explícitamente.
Iteración en todos los mensajes
En el ejemplo siguiente se muestra la iteración de todos los mensajes del buzón de un usuario.
Sugerencia
En este ejemplo se establece un tamaño de página pequeño mediante el top parámetro para fines de demostración. Puede establecer el tamaño de página en 999 para minimizar el número de solicitudes necesarias.
var messages = await graphClient.Me.Messages
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Top = 10;
requestConfiguration.QueryParameters.Select = new string[] { "sender", "subject", "body" };
requestConfiguration.Headers.Add("Prefer", "outlook.body-content-type=\"text\"");
});
var pageIterator = PageIterator<Message,MessageCollectionResponse>
.CreatePageIterator(
graphClient,
messages,
// Callback executed for each item in
// the collection
(m) =>
{
Console.WriteLine(m.Subject);
return true;
},
// Used to configure subsequent page
// requests
(req) =>
{
// Re-add the header to subsequent requests
req.Headers.Add("Prefer", "outlook.body-content-type=\"text\"");
return req;
}
);
await pageIterator.IterateAsync();
// Makes request to fetch mails list.
let response: PageCollection = await client
.api("/me/messages?$top=10&$select=sender,subject,body")
.header('Prefer', 'outlook.body-content-type="text"')
.get();
// A callback function to be called for every item in the collection.
// This call back should return boolean indicating whether not to
// continue the iteration process.
let callback: PageIteratorCallback = (data) => {
console.log(data.subject);
return true;
};
// A set of request options to be applied to
// all subsequent page requests
let requestOptions: GraphRequestOptions = {
// Re-add the header to subsequent requests
headers: {
'Prefer': 'outlook.body-content-type="text"'
}
};
// Creating a new page iterator instance with client a graph client
// instance, page collection response from request and callback
let pageIterator = new PageIterator(client, response, callback, requestOptions);
// This iterates the collection until the nextLink is drained out.
await pageIterator.iterate();
MessageCollectionPage messagesPage = graphClient.me().messages()
.buildRequest(new HeaderOption("Prefer", "outlook.body-content-type=\"text\""))
.select("Sender,Subject,Body")
.top(10)
.get();
while(messagesPage != null) {
final List<Message> messages = messagesPage.getCurrentPage();
final MessageCollectionRequestBuilder nextPage = messagesPage.getNextPage();
if (nextPage == null) {
break;
} else {
messagesPage = nextPage.buildRequest(
// Re-add the header to subsequent requests
new HeaderOption("Prefer", "outlook.body-content-type=\"text\"")
).get();
}
}
Importante
El SDK de Microsoft Graph para Go está actualmente en versión preliminar. No se admite el uso de este SDK en producción.
import (
abstractions "github.com/microsoft/kiota-abstractions-go"
msgraphcore "github.com/microsoftgraph/msgraph-sdk-go-core"
"github.com/microsoftgraph/msgraph-sdk-go/me"
"github.com/microsoftgraph/msgraph-sdk-go/models"
)
headers := abstractions.NewRequestHeaders()
headers.Add("Prefer", "outlook.body-content-type=\"text\"")
query := me.MessagesRequestBuilderGetQueryParameters{
Select: []string{"body", "sender", "subject"},
}
options := me.MessagesRequestBuilderGetRequestConfiguration{
Headers: headers,
QueryParameters: &query,
}
result, err := client.Me().Messages().Get(context.Background(), &options)
// Initialize iterator
pageIterator, err := msgraphcore.NewPageIterator(
result, client.GetAdapter(), models.CreateMessageCollectionResponseFromDiscriminatorValue)
// Any custom headers sent in original request should also be added
// to the iterator
pageIterator.SetHeaders(headers)
// Iterate over all pages
iterateErr := pageIterator.Iterate(context.Background(), func(pageItem interface{}) bool {
message := pageItem.(models.Messageable)
fmt.Printf("%s\n", *message.GetSubject())
// Return true to continue the iteration
return true
})
Detener y reanudar la iteración
Algunos escenarios requieren detener el proceso de iteración para realizar otras acciones. Es posible pausar la iteración devolviendo false de la devolución de llamada de iteración. La iteración se puede reanudar llamando al resume método en PageIterator.
int count = 0;
int pauseAfter = 25;
var messages = await graphClient.Me.Messages
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Top = 10;
requestConfiguration.QueryParameters.Select = new string[] { "sender", "subject" };
});
var pageIterator = PageIterator<Message, MessageCollectionResponse>
.CreatePageIterator(
graphClient,
messages,
(m) =>
{
Console.WriteLine(m.Subject);
count++;
// If we've iterated over the limit,
// stop the iteration by returning false
return count < pauseAfter;
}
);
await pageIterator.IterateAsync();
while (pageIterator.State != PagingState.Complete)
{
Console.WriteLine("Iteration paused for 5 seconds...");
await Task.Delay(5000);
// Reset count
count = 0;
await pageIterator.ResumeAsync();
}
let count: number = 0;
let pauseAfter: number = 25;
let response: PageCollection = await client
.api('/me/messages?$top=10&$select=sender,subject')
.get();
let callback: PageIteratorCallback = (data) => {
result = `${result}${data.subject}\n`;
console.log(data.subject);
count++;
// If we've iterated over the limit,
// stop the iteration by returning false
return count < pauseAfter;
};
let pageIterator = new PageIterator(client, response, callback);
await pageIterator.iterate();
while (!pageIterator.isComplete()) {
console.log('Iteration paused for 5 seconds...');
await new Promise(resolve => setTimeout(resolve, 5000));
// Reset count
count = 0;
await pageIterator.resume();
}
// not supported in java SDK
Importante
El SDK de Microsoft Graph para Go está actualmente en versión preliminar. No se admite el uso de este SDK en producción.
import (
abstractions "github.com/microsoft/kiota-abstractions-go"
msgraphcore "github.com/microsoftgraph/msgraph-sdk-go-core"
"github.com/microsoftgraph/msgraph-sdk-go/me"
"github.com/microsoftgraph/msgraph-sdk-go/models"
)
headers := abstractions.NewRequestHeaders()
headers.Add("Prefer", "outlook.body-content-type=\"text\"")
query := me.MessagesRequestBuilderGetQueryParameters{
Select: []string{"body", "sender", "subject"},
}
options := me.MessagesRequestBuilderGetRequestConfiguration{
Headers: headers,
QueryParameters: &query,
}
result, err := client.Me().Messages().Get(context.Background(), &options)
// Initialize iterator
pageIterator, err := msgraphcore.NewPageIterator(
result, client.GetAdapter(), models.CreateMessageCollectionResponseFromDiscriminatorValue)
// Any custom headers sent in original request should also be added
// to the iterator
pageIterator.SetHeaders(headers)
// Pause iterating after 25
var count, pauseAfter = 0, 25
// Iterate over all pages
iterateErr := pageIterator.Iterate(context.Background(), func(pageItem interface{}) bool {
message := pageItem.(models.Messageable)
count++
fmt.Printf("%d: %s\n", count, *message.GetSubject())
// Once count = 25, this returns false,
// Which pauses the iteration
return count < pauseAfter
})
// Pause 5 seconds
fmt.Printf("Iterated first %d messages, pausing for 5 seconds...\n", pauseAfter)
time.Sleep(5 * time.Second)
fmt.Printf("Resuming iteration...\n")
// Resume iteration
iterateErr = pageIterator.Iterate(context.Background(), func(pageItem interface{}) bool {
message := pageItem.(models.Messageable)
count++
fmt.Printf("%d: %s\n", count, *message.GetSubject())
// Return true to continue the iteration
return true
})