GitHub GraphQL recipe
Source: GitHubSample/ · paginated GraphQL queries over GitHub's API (with a local-file fallback for offline dev).
Owns in the academic graph: repositories, issues, pull requests, reviews, GitHub users, topic tags.
What it teaches
- GraphQL pagination using the
pageInfo { endCursor hasNextPage }envelope. Node.FromKey(...)to link to nodes built by other queries in the same run.[Timestamp]attribute for proper time-aware properties.- Respecting rate limits via the standard
X-RateLimit-*headers.
Query and pagination
public const string RepositoriesQuery = @"
query($owner: String!, $after: String) {
organization(login: $owner) {
repositories(first: 25, after: $after) {
pageInfo { hasNextPage endCursor }
nodes {
nameWithOwner
stargazerCount
repositoryTopics(first: 20) { nodes { topic { name } } }
}
}
}
}";
await foreach (var repo in source.PagedRequest<GitHubIngest.RepoDoc>(
GitHubIngest.RepositoriesQuery,
"organization.repositories",
repoVars))
{
GitHubIngest.IngestRepo(graph, repo);
repoKeys.Add(repo.NameWithOwner);
}
Schema (excerpt)
[Node]
public class Repository
{
[Key] public string NameWithOwner { get; set; } = string.Empty;
[Property] public string Description { get; set; } = string.Empty;
[Property] public int Stars { get; set; }
[Timestamp] public DateTimeOffset CreatedAt { get; set; }
}
[Node]
public class Skill
{
// Shared with CSV/JSON recipes — merges automatically.
[Key] public string Name { get; set; } = string.Empty;
}
Configuration
| Variable | Purpose | Default |
|---|---|---|
RECIPE_GH_TOKEN |
GitHub fine-grained PAT (blank → local mode) | (blank) |
RECIPE_GH_ORG |
Organization name | (required for live mode) |
RECIPE_LOCAL_ROOT |
Local fallback root | data/ |
Reuse notes
- The
pageInfo/nodesenvelope is GitHub's, but the same recipe code works against Shopify, Linear, and GitLab GraphQL endpoints with minor query tweaks. - Use
[Timestamp]on date-time fields so the workspace handles them as proper time properties rather than strings.