Extract GitHub GraphQL code to a module (#119)

Summary:
Per #117, we want to develop an ad hoc pagination API written
specifically against the query that we use to interact with GitHub.
The pagination logic should be separate from the logic to actually fetch
the repo, but should be colocated with the query itself, so this commit
extricates the query from `fetchGithubRepo.js` into a new module.

Test Plan:
Existing tests pass, including `fetchGithubRepoTest.sh`.

wchargin-branch: extract-github-graphql
This commit is contained in:
William Chargin 2018-04-05 00:08:52 -07:00 committed by GitHub
parent 806c5e5687
commit fbb6ec28db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 91 deletions

View File

@ -6,8 +6,8 @@
import fetch from "isomorphic-fetch"; import fetch from "isomorphic-fetch";
import type {Body} from "../../graphql/queries"; import {stringify, inlineLayout} from "../../graphql/queries";
import * as GraphQLQueries from "../../graphql/queries"; import {createQuery, createVariables} from "./graphql";
/** /**
* Scrape data from a GitHub repo using the GitHub API. * Scrape data from a GitHub repo using the GitHub API.
@ -45,101 +45,14 @@ export default function fetchGithubRepo(
throw new Error(`Invalid token: ${token}`); throw new Error(`Invalid token: ${token}`);
} }
const query = GraphQLQueries.stringify.body( const query = stringify.body(createQuery(), inlineLayout());
createQuery(), const variables = createVariables(repoOwner, repoName);
GraphQLQueries.inlineLayout()
);
const variables = {repoOwner, repoName};
const payload = {query, variables}; const payload = {query, variables};
return postQuery(payload, token); return postQuery(payload, token);
} }
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",

View File

@ -0,0 +1,92 @@
// @flow
import type {Body} from "../../graphql/queries";
import {build} from "../../graphql/queries";
export function createQuery(): Body {
const b = 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;
}
export function createVariables(repoOwner: string, repoName: string) {
return {repoOwner, repoName};
}