wip: use GraphQL API to fetch issues and pull requests#455
wip: use GraphQL API to fetch issues and pull requests#455cheshire137 wants to merge 12 commits intogitpoint:masterfrom
Conversation
Since project link was removed, this is the new reference to the preferred issues to work on.
I ran `yarn contributors:generate` after I added myself to .all-contributorsrc.
|
Well done, it's time to GraphQL! @cheshire137 there is another approach to do GraphQL queries, we already discussed this in PR #347: you pass currently a ready query (with values variables), but instead you can only pass the query and variables to it. We considered this way, because GraphQL queries may be large and we wanted to store them in separate files, but by now we have not decided how and where to store them. @machour @housseindjirdeh is not it? |
|
This looks solid!! 💃 I'm still relatively new to GraphQL and I'm not sure @lex111. It does look like queries can be quite large so do you think we should keep them in the And with regards to formatting changes, you're right :) We're using prettier as a pre-commit hook hence why you're noticing a few things different. |
|
Wow wow, that's looking just amazing @cheshire137 ! I've been busy on my side with another PR that I just posted: #457. It's a big refactoring of our current store, and it introduces a redux middleware and a completely new REST API that is aiming at replacing Could you give it a read on your side, and see how this new store could be used for graphql? |
|
@lex111, I like what you're doing with the variable declarations in #347, like
I agree GraphQL queries can get long, especially if they stay readable by being broken onto multiple lines. I like the idea of keeping multiple queries in a file, but only the ones related to each other. So not one giant file of all the GraphQL queries used in the whole app. I think src/api/queries/repositories.js or src/repository/repository.queries.js makes sense in this branch. I'll pick one style but I'm happy to change.
Thanks! Beware right now when you click an issue or PR from a repo page, the issue/PR page will be empty of data.
Yes! I'll look. |
machour
left a comment
There was a problem hiding this comment.
I tested & reviewed your PR @cheshire137, and it's coming out nicely.
I left a few comments here and there with some advices / questions.
I know this is still WIP, but the issues/pulls screens seems to be empty when I visit them. Is that intended for now or did I hit a bug?
Thanks again for all this, I couldn't think of a better time for implementing GraphQL!
| Please feel free to take on any issue that's currently open. You could look at | ||
| [issues labeled "high priority"](https://github.com/gitpoint/git-point/issues?q=is%3Aopen+is%3Aissue+label%3A%22high+priority%22), | ||
| but feel free to resolve any issue that you would enjoy working on even if it happens to be a low priority. | ||
|
|
There was a problem hiding this comment.
not sure this should be a part of this PR
There was a problem hiding this comment.
Fair enough, personally don't mind having this correction included however.
|
|
||
| if (response.status >= 200 && response.status < 300) { | ||
| return json.data; | ||
| } |
There was a problem hiding this comment.
Could we test for failed response.statuses instead before doing the JSON.parse() ?
There was a problem hiding this comment.
The GraphQL API returns JSON on error as well as success. I do the JSON parsing ahead of this line so I can get the message out of the body as to why the query failed, to put in the Error.
There was a problem hiding this comment.
Didn't know that, thanks for clarifying it, it's perfect that way then.
There was a problem hiding this comment.
I might be able to do await response.json() instead of parsing the body myself, though. 🤔
There was a problem hiding this comment.
And it makes more sense along with Promise.reject() 👌
|
|
||
| error.response = response; | ||
| throw error; | ||
| }, |
There was a problem hiding this comment.
What about return Promise.reject(error.response) instead?
| method: METHOD.POST, | ||
| headers: { | ||
| Authorization: `token ${accessToken}`, | ||
| }, |
There was a problem hiding this comment.
Haven't tried GraphQL on my side yet. Are this header enough? Shouldn't we be passing a User-Agent ? (GitPoint/Android-3.2 for example).
I'd like to have it shared between GraphQL & Rest
There was a problem hiding this comment.
This is all that's necessary to use the endpoint, though I could add a user-agent header. See the example at https://developer.github.com/v4/guides/forming-calls/#communicating-with-graphql.
For trying the GraphQL API, I like https://developer.github.com/v4/explorer/, which lets you run queries as your GitHub user in the browser.
| if (type === 'issue') { | ||
| return issue.state === 'closed' ? 'issue-closed' : 'issue-opened'; | ||
| return issue.state === 'CLOSED' ? 'issue-closed' : 'issue-opened'; | ||
| } |
There was a problem hiding this comment.
CLOSED, OPEN, .. should be moved in a string enum
| const response = await v4.call(v4.parameters(accessToken, body)); | ||
|
|
||
| return response; | ||
| }, |
There was a problem hiding this comment.
is post() the only method that will exist to access GraphQL ?
If that's the case, maybe we can merge call() & parameters() inside it
There was a problem hiding this comment.
Yep, all requests whether they're reading or writing, are POSTs; see https://developer.github.com/v4/guides/forming-calls/#communicating-with-graphql.
I can merge these methods!
| } else if (params.issue) { | ||
| issueRepository = params.issue.repository.nameWithOwner; | ||
| } | ||
| const repositoryUrl = `https://api.github.com/repos/${issueRepository}`; |
| const openIssues = pureIssues.filter(issue => issue.state === 'open'); | ||
| const openPulls = pullRequests.filter(pull => pull.state === 'OPEN'); | ||
| const openIssues = issues.filter(issue => issue.state === 'OPEN'); | ||
| const showFork = |
There was a problem hiding this comment.
Using reactotron, I see that when we navigate to a repository screen, we pull 100 issues & 100 pull requests from the repo.
If the user doesn't click on "View All" for issues or PR, this is a waste of data & Github credit.
Could we have a single GraphQL query that retrieves only the 3 most recent & open issues & PR instead?
There was a problem hiding this comment.
Yes! I wondered about this, but was trying to translate directly from how the v3 API was being used to v4. I'll change the code that's slicing the first three results in JavaScript so that instead we just pass first: 3 to the API.
That's intended! It's where I left off. |
|
Thanks for the feedback @cheshire137. I remembered that @andrewda did an extensive study on GraphQL ressources limitation, and the queries scores in #141, and I wonder in what place should we use GraphQL, and where we should instead rely on REST to stay under the limits. The way I see it, GraphQL is great for screens built with various data from different endpoint. The repository screen is a good example, here are the REST requests currently made:
Do you think these six REST calls could be reduced to a single GraphQL query, that would return:
On the other hand, I'm not sure GraphQL would be preferable to REST if we just want to paginate the issues list for example, as we're able to get 100 issues in a single REST call, without consuming any credit available for GraphQL calls. I'm curious about your thoughts on that |
To my knowledge, there's not a connection in GraphQL that returns a repository's contributors. How were you getting at this list via the REST API? The other data in your list--repo basic info, if the README exists, etc.--all sound fine to fetch via GraphQL.
This is something to consider. The biggest reason to use GraphQL to me is to get at the data we want more directly, and without getting a bunch of other data we don't need. |
Can you share a link with info about GraphQL credits? |
|
Contributors support seems to have been just added a few days ago: https://platform.github.community/t/cant-access-the-contributors-of-a-repository/1848/8?u=machour With rest, we are using this endpoint https://api.github.com/repos/gitpoint/git-point/contributors Agreed with you, being able to hand pick the returned fields is gold with GraphQL. Weird REST doesn't provide the same thing via a Here's for GraphQL scoring system at GitHub: https://developer.github.com/v4/guides/resource-limitations/ (haven't done any math yet, so I'm maybe worrying for nothing) |
|
Looks like 100 issues in GraphQL should just cost 1, and that that rate limit should be shared with the REST API. So using 1 credit for GraphQL means there's 1 fewer for REST. It starts to jump if we nest connections (like grab 100 repos and for each of those, grab 100 issues). We can also stick |
Oh nice! Then your whole list can be fetched via GraphQL if we want. |
| ] | ||
| }, | ||
| { | ||
| "login": "cheshire137", |
|
Time got away with me on this one! If someone else wanted to take this over from me, I'd be happy to let them. |
|
Closing this PR as it's superseded by the ongoing store refactoring. Thank you so much for all the efforts and explanations @cheshire137, the next implementation is inspired by your work! |
This is a work in progress to solicit some feedback about the approach. If this seems worthwhile, I'll continue working on this branch!
This branch partially addresses #141 by updating how a repository's issues and pull requests are fetched, so we use v4 of the GitHub API instead of v3. What's missing currently is the views for individual issues and pull requests are not working because they're still expecting data in the v3 format instead of v4. I added a new
getPullRequestsfunction because PRs are not automatically returned in the list of issues in v4 of the API.There are a couple style changes I didn't intentionally make. 🤔 I believe when I commit my changes, a git hook is doing some automatic style fixes and it's adjusting lines I didn't otherwise touch. Specifically, it's removing extra parentheses from around components. Is this expected?
This branch also adds me to the contributors list. 🎉