Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paging in Microsoft.Graph.DirectoryObjects.GetByIds #2483

Closed
ssteiner opened this issue May 13, 2024 · 6 comments
Closed

Paging in Microsoft.Graph.DirectoryObjects.GetByIds #2483

ssteiner opened this issue May 13, 2024 · 6 comments
Labels
Question: SDK Status: No recent activity status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close type:question An issue that's a question

Comments

@ssteiner
Copy link

We're adapting our V5 code to remove the use of obsolete classes/methods. One of the things flagged was our way of getting a list of directory objects. I'm wondering - if this is my first request

            var payload = new Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostRequestBody
            {
                Ids = ids, 
                Types = objectTypes 
            };
            var req = graphServiceClient.DirectoryObjects.GetByIds.ToPostRequestInformation(payload);
            if (attributeList != null)
                req.URI = new Uri($"{req.URI}?$select={string.Join(",", attributeList.Select(o => o.FirstCharToLower()))}");
            //var items = await graphServiceClient.RequestAdapter.SendAsync(req, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsResponse.CreateFromDiscriminatorValue);
            var items = await graphServiceClient.RequestAdapter.SendAsync(req, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostResponse.CreateFromDiscriminatorValue);

and items.OdataNextLink is not null, what would be the correct API call to get the next page?

I've not found any method on GetByIdsPostRequestBody that would take a url.

@ssteiner ssteiner added the status:waiting-for-triage An issue that is yet to be reviewed or assigned label May 13, 2024
@andrueastman
Copy link
Member

Thanks for raising this @ssteiner

I believe it may be possible to use the pageIterator to collect all the items as below.

var collectedItems = new List<DirectoryObject>();
var pageIterator = PageIterator<DirectoryObject, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostResponse>.CreatePageIterator(graphClient, items, (item) => { collectedItems.Add(item); return true; });
await pageIterator.IterateAsync();

alternatively, you can use the WithUrl to create a new request information instance and modify it as below

            var nextRequest = graphServiceClient.DirectoryObjects.GetByIds.WithUrl(items.OdataNextLink).ToPostRequestInformation(new Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostRequestBody
            {
            });
            nextRequest.HttpMethod = Microsoft.Kiota.Abstractions.Method.GET;

            var nextItems = await graphServiceClient.RequestAdapter.SendAsync(req, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostResponse.CreateFromDiscriminatorValue);

@andrueastman andrueastman added Question: SDK Needs: Author Feedback type:question An issue that's a question and removed status:waiting-for-triage An issue that is yet to be reviewed or assigned labels May 14, 2024
@trust11
Copy link

trust11 commented May 21, 2024

This exception will occur when you request more than 1000 IDs.

Microsoft.Kiota.Abstractions.ApiException: 'The server returned an unexpected status code and no error factory is registered for this code: 400'

It appears to me that there is no built-in pagination.

 var payload = new Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostRequestBody
            {
                Ids = ids.Take(1001).ToList(),
                Types = objectTypes
            };
            var req = graphServiceClient.DirectoryObjects.GetByIds.ToPostRequestInformation(payload);
            if (attributeList != null)
                req.URI = new Uri($"{req.URI}?$select={string.Join(",", attributeList.Select(o => o.FirstCharToLower()))}");
            var items = await graphServiceClient.RequestAdapter.SendAsync(req, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostResponse.CreateFromDiscriminatorValue);

@andrueastman
Copy link
Member

I suspect the API may have a limit as to many Ids can be passed as a parameter.

Any chance you can share the error if you pass the errorMapiing parameter as below?

            var errorMapping = new Dictionary<string, ParsableFactory<IParsable>> 
            {
                { "XXX", ODataError.CreateFromDiscriminatorValue}
            };
            var items = await graphServiceClient.RequestAdapter.SendAsync(req, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostResponse.CreateFromDiscriminatorValue, errorMapping);

@trust11
Copy link

trust11 commented May 22, 2024

Here is the result -> Number of included identifiers cannot exceed '1000'

Exception in GetDirectoryObjects: Number of included identifiers cannot exceed '1000'. at at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.ThrowIfFailedResponse(HttpResponseMessage response, Dictionary2 errorMapping, Activity activityForAttributes, CancellationToken cancellationToken) at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.SendAsync[ModelType](RequestInformation requestInfo, ParsableFactory1 factory, Dictionary2 errorMapping, CancellationToken cancellationToken) at Microsoft.Kiota.Http.HttpClientLibrary.HttpClientRequestAdapter.SendAsync[ModelType](RequestInformation requestInfo, ParsableFactory1 factory, Dictionary2 errorMapping, CancellationToken cancellationToken) at AzureADMsGraph.AzureADClient.GetDirectoryObjects(List1 ids, List1 objectTypes, List1 attributeList, IOperationContainer container)

So it has no paging, I'm wrong?

@andrueastman
Copy link
Member

I believe what this means is that you can't pass more than 1000 items at a time as a parameter.

However, if the response has a nextLink you can page through it as suggested above.

Thanks for raising this @ssteiner

I believe it may be possible to use the pageIterator to collect all the items as below.

var collectedItems = new List<DirectoryObject>();
var pageIterator = PageIterator<DirectoryObject, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostResponse>.CreatePageIterator(graphClient, items, (item) => { collectedItems.Add(item); return true; });
await pageIterator.IterateAsync();

alternatively, you can use the WithUrl to create a new request information instance and modify it as below

            var nextRequest = graphServiceClient.DirectoryObjects.GetByIds.WithUrl(items.OdataNextLink).ToPostRequestInformation(new Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostRequestBody
            {
            });
            nextRequest.HttpMethod = Microsoft.Kiota.Abstractions.Method.GET;

            var nextItems = await graphServiceClient.RequestAdapter.SendAsync(req, Microsoft.Graph.DirectoryObjects.GetByIds.GetByIdsPostResponse.CreateFromDiscriminatorValue);

@andrueastman andrueastman added the status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close label May 23, 2024
Copy link
Contributor

This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question: SDK Status: No recent activity status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close type:question An issue that's a question
Projects
None yet
Development

No branches or pull requests

3 participants