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
Output a single JSON document from api --paginate
#1268
Comments
Thanks for the feedback! I think reducing is a good idea, but it might be tricky to achieve for GraphQL requests. That's why we currently dump raw JSON responses without changing them. |
At least document the current behavior. I would have assumed that $ gh api -XGET --paginate /repos/:owner/:repo/pulls -F state=closed | jq ' . | length'
100
100
100
54 |
api --paginate
Will GraphQL always output a JSON object? If so, could |
Individual API responses during REST pagination always return JSON arrays. We can easily concatenate those arrays into a single one. Individual API responses during GraphQL pagination will return something like this: {
"data": {
"repository": {
"branchProtectionRules": {
"nodes": ["PAGINATED DATA APPEARS HERE"],
"pageInfo": {
"hasNextPage": false,
"endCursor": "Y3Vyc29yOnYyOpK0MjAyMC0wNS0yN1QxMjowNDo1N1rOAPZ2gA=="
}
}
}
}
} If we concatenate each of these responses as a whole into a JSON array, it will significantly modify the overall structure of the response and might be confusing to parse. Instead, we should probably identify the nested array that's being paginated and concatenate all results into that one. In the example above, the paginated array is As a workaround until this is solved, I would use the # should produce a single JSON array of all paginated result concatenated:
gh api graphql -f query='QUERY' --paginate --jq '.data.repository.branchProtectionRules.nodes[]' | jq -s |
I had considered that, but After playing around with it a bunch last night, I discovered a solution using As for backward-compatible support - since templates (maybe) or processing raw responses (definitely) will change - a switch to opt into this behavior would be ideal. As for cleaning up the |
Hey, I've been working on https://github.com/ldelossa/gh.nvim. This Neovim plugin uses the Ideally, if you specify "--paginate" we recieve one json object with all the data that can be iterated. Another solution would be to allow the a "slurp" flag to the --jq flag. I'm not seeing a great way to paginate manually with the |
I started working on a possible solution. Basically, a utility function that will merge JSON by appending arrays and overwriting properties. Effectively,
This also has the benefit that will fix any template using gh api graphql --paginate -f owner=cli -f name=cli -f query='query($owner:String!,$name:String!,$endCursor:String){repository(owner:$owner,name:$name){labels(first:10,after:$endCursor){nodes{name,description},pageInfo{hasNextPage,endCursor}}}}' --template '{{range .data.repository.labels.nodes}}{{tablerow .name .description}}{{end}}{{tablerender}}' This renders misaligned columns:
The workaround is simple enough: don't use So I'm thinking that |
Im not familiar with graphql pagination or "rendertable" does this effect me if I simply want a aggregated array of pagination responses? One other question is, how does the "--paginate" flag work with nested Graphql queries? For instance, I typically retrieve 100 pullRequestReviewThreads which themselves request 100 pullReviewRequestComments - would the inner comments be paginated also? |
My reply was intended for @mislav, about a possible solution. As he mentioned, for now you can pipe the output to |
This is everything I needed right here... I think... It certainly solves my immediate need. Thank you. |
@justin-octo that's a good idea. @mislav could we use my code changes behind an opt-in |
@mislav should this really be closed, though? GraphQL responses still have this problem and given that's what GitHub documents as preferred over REST, shouldn't we still tackle this problem like we had previously discussed? Should I open a separate issue to track it just for GraphQL responses instead? |
@heaths Sorry for prematurely closing. I set for myself a goal to first solve the pagination for REST requests, and only later think about a potential approach to GraphQL ones that satisfies the streaming requirement. However, I will not work on this solution anymore, as I have left GitHub and the CLI team some weeks ago. I think that a proper solution to GraphQL pagination wouldn't just solve the JSON array problem, but also alleviate the need for the GraphQL query to be specially prepared for CLI pagination. Ideally, the user should just be able to supply the "selector" within a GraphQL query to be paginated, and
Implementing this would be non-trivial, but I think that GraphQL pagination should either have a full solution, or no solution (i.e. either keep exactly what we have now, or delegate a pagination implementation to the user of |
Sorry to see you go! Hope you have a great summer and great success in your future endeavors. I would love to see this implemented if anyone else on the team is available. If they are please hand it off to them :) If not, I have been using |
@mislav I echo what @justin-octo says. Thanks for all your hard work on the CLI over the years. @justin-octo I do have a PR open that solves this for both JSON and GraphQL in a way, though it changes streaming; however, I don't think that's a problem given - without |
@mislav wrote,
Conceptually I like it, but seems the only robust way to do that is to hit the service once to get the schema based on the user query to find where (and probably err on more than one) the pagination response schema should go. Or should the CLI even cache the full schema? Are etags (or conditional requests in general) support? Might be overkill for this, though. The schema is fairly large. |
Summarizing meeting between @heaths, @samcoe, @williammartin and myself:
Once again, big thanks to @heaths for his diligence in addressing this recurring need for the GitHub CLI community! ✨ |
I'll also add a bevy of tests for mergo to make sure we don't regress any behavior now or later e.g., date-time strings should never change format. It's unlikely already since we're just working with |
Partly resolves cli/cli#1268 and replaces cli/cli#5652
Partly resolves cli#1268 and replaces cli#5652. Requires cli/go-gh#148 to be merged and optionally released.
Partly resolves cli#1268 and replaces cli#5652. Requires cli/go-gh#148 to be merged and optionally released.
Partly resolves cli#1268 and replaces cli#5652. Requires cli/go-gh#148 to be merged and optionally released.
Partly resolves cli#1268 and replaces cli#5652. Requires cli/go-gh#148 to be merged and optionally released.
Partly resolves cli#1268 and replaces cli#5652. Requires cli/go-gh#148 to be merged and optionally released.
Partly resolves cli#1268 and replaces cli#5652. Requires cli/go-gh#148 to be merged and optionally released.
My example from #1268 (comment) now just works in 2.48.0. Thanks! |
thank you guys |
Reading your example and reproducing targeting
I was very confused about whether we'd broken something in pagination. Turns out Thanks for the feedback! |
Just as a stress test, I checked on |
FWIW, technically that was using Nate's merging of only REST array responses done previously, and does not use anything of the my PR that was just merged. Good to know it wasn't regressed, but the command should've worked already. |
Yeh I just bisected it because it occurred to me that nothing should have changed without the addition of |
First of all, thanks for the
--paginate
flag. Although I'd like to get one array of objects instead. Today I'm usingjq
to do the work:The text was updated successfully, but these errors were encountered: