Use structured GraphQL query API in GitHub fetcher (#94)

Summary:
In addition to being nicer on the eyes, this enables the query to be
statically analyzed (e.g., by an auto-pagination API) and used by other
modules.

Test Plan:
Manually running
```shell
$ yarn backend
$ GITHUB_TOKEN="<your_token>" src/plugins/github/fetchGitHubRepoTest.sh
```
succeeds.

wchargin-branch: use-structured-graphql-queries
This commit is contained in:
William Chargin 2018-03-20 15:29:31 -07:00 committed by GitHub
parent ab619432e1
commit f02e0610be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 91 additions and 99 deletions

View File

@ -6,6 +6,9 @@
import fetch from "isomorphic-fetch"; import fetch from "isomorphic-fetch";
import type {Body} from "../../graphql/queries";
import * as GraphQLQueries from "../../graphql/queries";
/** /**
* Scrape data from a GitHub repo using the GitHub API. * Scrape data from a GitHub repo using the GitHub API.
* *
@ -42,105 +45,10 @@ export default function fetchGitHubRepo(
throw new Error(`Invalid token: ${token}`); throw new Error(`Invalid token: ${token}`);
} }
const query = `query FetchData($repoOwner: String!, $repoName: String!) { const query = GraphQLQueries.stringify.body(
repository(owner: $repoOwner, name: $repoName) { createQuery(),
issues(first: 100) { GraphQLQueries.inlineLayout()
pageInfo { );
hasNextPage
}
nodes {
id
title
body
number
author {
...whoami
}
comments(first: 20) {
pageInfo {
hasNextPage
}
nodes {
id
author {
...whoami
}
body
url
}
}
}
}
pullRequests(first: 100) {
pageInfo {
hasNextPage
}
nodes {
id
title
body
number
author {
...whoami
}
comments(first: 20) {
pageInfo {
hasNextPage
}
nodes {
id
author {
...whoami
}
body
url
}
}
reviews(first: 10) {
pageInfo {
hasNextPage
}
nodes {
id
body
author {
...whoami
}
state
comments(first: 10) {
pageInfo {
hasNextPage
}
nodes {
id
url
body
author {
...whoami
}
}
}
}
}
}
}
}
}
fragment whoami on Actor {
__typename
login
... on User {
id
}
... on Organization {
id
}
... on Bot {
id
}
}
`;
const variables = {repoOwner, repoName}; const variables = {repoOwner, repoName};
const payload = {query, variables}; const payload = {query, variables};
return postQuery(payload, token); return postQuery(payload, token);
@ -148,6 +56,90 @@ export default function fetchGitHubRepo(
const GITHUB_GRAPHQL_SERVER = "https://api.github.com/graphql"; const GITHUB_GRAPHQL_SERVER = "https://api.github.com/graphql";
function createQuery(): Body {
const b = GraphQLQueries.build;
const makePageInfo = () => b.field("pageInfo", {}, [b.field("hasNextPage")]);
const makeAuthor = () => b.field("author", {}, [b.fragmentSpread("whoami")]);
const body: Body = [
b.query(
"FetchData",
[b.param("repoOwner", "String!"), b.param("repoName", "String!")],
[
b.field(
"repository",
{owner: b.variable("repoOwner"), name: b.variable("repoName")},
[
b.field("issues", {first: b.literal(100)}, [
makePageInfo(),
b.field("nodes", {}, [
b.field("id"),
b.field("title"),
b.field("body"),
b.field("number"),
makeAuthor(),
b.field("comments", {first: b.literal(20)}, [
makePageInfo(),
b.field("nodes", {}, [
b.field("id"),
makeAuthor(),
b.field("body"),
b.field("url"),
]),
]),
]),
]),
b.field("pullRequests", {first: b.literal(100)}, [
makePageInfo(),
b.field("nodes", {}, [
b.field("id"),
b.field("title"),
b.field("body"),
b.field("number"),
makeAuthor(),
b.field("comments", {first: b.literal(20)}, [
makePageInfo(),
b.field("nodes", {}, [
b.field("id"),
makeAuthor(),
b.field("body"),
b.field("url"),
]),
]),
b.field("reviews", {first: b.literal(10)}, [
makePageInfo(),
b.field("nodes", {}, [
b.field("id"),
b.field("body"),
makeAuthor(),
b.field("state"),
b.field("comments", {first: b.literal(10)}, [
makePageInfo(),
b.field("nodes", {}, [
b.field("id"),
b.field("body"),
b.field("url"),
makeAuthor(),
]),
]),
]),
]),
]),
]),
]
),
]
),
b.fragment("whoami", "Actor", [
b.field("__typename"),
b.field("login"),
b.inlineFragment("User", [b.field("id")]),
b.inlineFragment("Organization", [b.field("id")]),
b.inlineFragment("Bot", [b.field("id")]),
]),
];
return body;
}
function postQuery(payload, token) { function postQuery(payload, token) {
return fetch(GITHUB_GRAPHQL_SERVER, { return fetch(GITHUB_GRAPHQL_SERVER, {
method: "POST", method: "POST",