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

Pagination not working on GET /Users or /Groups #83

Open
OutstandingBillNeal opened this issue Mar 28, 2022 · 1 comment
Open

Pagination not working on GET /Users or /Groups #83

OutstandingBillNeal opened this issue Mar 28, 2022 · 1 comment

Comments

@OutstandingBillNeal
Copy link

I think there's a design flaw around pagination. The provider implementation in WebHostSample seems to be responsible for pagination (although it does not currently .Skip(), it just .Take()s), but ProviderBase (in SystemForCrossDomainIdentityManagement) is responsible for setting TotalResults. ProviderBase cannot know the correct value for TotalResults if the result it receives from the implementation is already paginated.

The specification says (https://datatracker.ietf.org/doc/html/rfc7644#page-25) that "totalResults [should specify] the total number of results matching the client query". In the example provided by IETF, GET /Users?startIndex=1&count=10 yields

{
  "totalResults":100,
  "itemsPerPage":10,
  "startIndex":1,
  "schemas":["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
  "Resources":[{
    ...
  }]
}

As well as correcting TotalResults, an ideal implementation would also be mindful of efficiency concerns. That might enable the provider to return TotalResults along with the results, so that the implementation can decide whether to use the same query or a different one to ascertain its value.

For example, it might be more efficient to do this

// UserProvider
var results = _db.UserProfiles
    .Where(u => u.ClientId == "xyz")
    .Skip(startIndex)
    .Take(count)
    .Select(some DTO);
var totalResults = _db.UserProfiles
    .Count(u => u.ClientId == "xyz");

than this

// UserProvider
var allResources = _db.UserProfiles
    .Where(u => u.ClientId == "xyz")
    .Select(some DTO);

// ProviderBase
var results = allResources
    .Skip(startIndex)
    .Take(count);
var totalResults = allResources.Count();
@Sefriol
Copy link

Sefriol commented May 21, 2024

I think the idea of ProviderBase is to be very low effort implementation where end user does not need to implement everything to get the basic functionality. For most cases, database could handle the pagination as a whole.

For WebHostSample, override could be done which implements PaginateQueryAsync function and deals with the issue as you stated.

Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 24, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 24, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 24, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 24, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 24, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 24, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 24, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue May 29, 2024
Sefriol added a commit to Sefriol/SCIMReferenceCode that referenced this issue Jun 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants