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

[Enhancement]: $first & $after keywords in REST & GQL #2246

Open
JerryNixon opened this issue Jun 4, 2024 · 3 comments
Open

[Enhancement]: $first & $after keywords in REST & GQL #2246

JerryNixon opened this issue Jun 4, 2024 · 3 comments
Labels
cri Customer Reported issue enhancement New feature or request triage issues to be triaged

Comments

@JerryNixon
Copy link
Contributor

JerryNixon commented Jun 4, 2024

This introduces $take/$skip in DAB REST and GraphQL endpoints.

Previous discussions had this feature as a synonym of $first/$after, but that is no longer the plan. The current plan is, instead, to introduce these as new keywords with similar, but not identical, functionality.

Data type Behavior REST GraphQL Current Status
$first integer TOP in T-SQL Yes, DAB supports this today
$after string Entity key(s) Yes, DAB supports this today
$take integer TOP in T-SQL (same as $first) No (this article)
$skip integer OFFSET in T-SQL No (this article)

Syntax

query {
  books(first: 5, after: "W3siVm1lIjoiaWQifV0=")
  {
    items {
      id
      title
    }
    hasNextPage
    endCursor
  }
}

query {
  books(take: 5, skip: 50)
  {
    items {
      id
      title
    }
    hasNextPage
  }
}

Note that $first, $take, and (later) $top are all synonyms of the same operations.

Benefits

The value of the $first/$after approach is that it allows developers to paginate in a reliable way. When the underlying collection changes, the next page is always the next page and does not reset because of ordinal position. In a busy table, this provides a consistent and non-jarring user experience.

The value of the $take/$skip approach is that it allows developers to paginate in a simple way, often in order to virtualize large datasets in visualization objects. It does not account for underlying collection changes but does return a programmatic page. It operates identically to the Take() and Skip() LINQ methods in .NET languages.

Bonus: $take/$skip are both keywords in OData and represent common expressions.

Proposed synonyms

The reason for synonyms would be to accommodate the OData specification.

Synonym Keyword REST GraphQL Current Status
$top $first No (this article)
$skiptoken $after No (this article)

Feedback

Customers have reported that using GraphQL keywords in REST endpoints instead of OData standard keywords causes some code to struggle when interacting with our endpoints. Other customers have reported that not supporting integer-based $take/$skip disqualifies some UI components looking for the standard.

@JerryNixon JerryNixon added bug Something isn't working triage issues to be triaged enhancement New feature or request and removed bug Something isn't working labels Jun 4, 2024
@raffaeler
Copy link

Great to see you logging this @JerryNixon.
Let me expand my initial request and add some more detail in relation to what you wrote here.

Revised specifications

In your table there is a semantic mismatch between $skip in oData and offset in GraphQL as for the official standards. Let me clarify with the following table whose columns specify:

  1. the oData standard specs
  2. the Graphql standard specs
  3. the current syntax for REST in DAB
  4. the current syntax for GraphQL in DAB
oData GraphQL DAB/REST DAB/GraphQL
Page size $top=number first:number $first=number first:number
Offset to skip $skip=number offset:number N/A N/A
Identifier to skip $skiptoken=string after:string N/A after:string

The perfect solution is to fully adhere to both standards by:

  • filling the three N/A holes
    • the offset keyword in GraphQL is also important
  • renaming the DAB/Rest $first to $top
    • This is a breaking changes and may hurt a bit at the beginning, but on the long term is definitely less confusing

Motivations

  1. Support the official oData and GraphQL keywords
  2. Allow replacing the WCF Data Services (oData) with DAB
  3. Allow replacing the ASP.NET Core OData implementation with DAB (see (A))
  4. The current .NET oData client library offers a Linq provider which transforms the Expression Trees into the oData query string. This string may include $skip and $top standard operators which should be therefore understood from the backend to correctly adhere to the client request.

Notes

(A) ASP.NET Core oData automatically exposes the CRUD for the tables but all the navigations must be manually coded. This is a major disadvantage compare to the old WCF Data Services and DAB.

HTH

@JerryNixon JerryNixon added the cri Customer Reported issue label Jun 12, 2024
@JerryNixon JerryNixon changed the title [Enhancement]: REST $first & $after synonyms [Enhancement]: $first & $after keywords in REST & GQL Jul 8, 2024
@JerryNixon
Copy link
Contributor Author

Remember @raffaeler, we need a solution that is backwards compatible with existing users of DAB. I have revised the plan but still need to talk to the engineering team about this, too. Would appreciate any feedback.

@raffaeler
Copy link

I understand the backward compatibility issues Jerry, but the compliance with standards should always come first. Even more when the original draft came from MS, even if oData was then given to oasis.

I am open to discuss but I don't really see great options to avoid the breaking change out of versioning the api with some headers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cri Customer Reported issue enhancement New feature or request triage issues to be triaged
Projects
None yet
Development

No branches or pull requests

2 participants