The Problem With GitHub REST API
To get a repo's stars, description, languages, and latest releases via REST, you need 4 separate API calls. With GraphQL, it's one call.
Setup
# You need a GitHub personal access token
# Settings → Developer settings → Personal access tokens → Generate
export GITHUB_TOKEN="ghp_your_token_here"
One Query, All the Data
import requests
def github_graphql(query, token):
r = requests.post(
"https://api.github.com/graphql",
json={"query": query},
headers={"Authorization": f"Bearer {token}"}
)
return r.json()
query = """
{
repository(owner: "facebook", name: "react") {
name
description
stargazerCount
forkCount
primaryLanguage { name }
releases(last: 3) {
nodes { name tagName publishedAt }
}
issues(states: OPEN) { totalCount }
pullRequests(states: OPEN) { totalCount }
}
}
"""
result = github_graphql(query, "your_token")
repo = result["data"]["repository"]
print(f"{repo[name]}: {repo[stargazerCount]}⭐ {repo[forkCount]} forks")
print(f"Open issues: {repo[issues][totalCount]}")
print(f"Open PRs: {repo[pullRequests][totalCount]}")
for r in repo["releases"]["nodes"]:
print(f" Release: {r[tagName]} ({r[publishedAt][:10]})")
REST equivalent: 4 API calls, 4x rate limit consumption, 4x latency.
GraphQL: 1 call, exact data you need, nothing extra.
Compare Multiple Repos at Once
query = """
{
react: repository(owner: "facebook", name: "react") {
...RepoInfo
}
vue: repository(owner: "vuejs", name: "core") {
...RepoInfo
}
svelte: repository(owner: "sveltejs", name: "svelte") {
...RepoInfo
}
}
fragment RepoInfo on Repository {
name
stargazerCount
forkCount
updatedAt
issues(states: OPEN) { totalCount }
}
"""
result = github_graphql(query, "your_token")
for name, repo in result["data"].items():
print(f"{repo[name]:15} {repo[stargazerCount]:>7}⭐ {repo[issues][totalCount]:>5} issues")
REST equivalent: 12 API calls. GraphQL: 1 call.
Search Repos by Topic
query = """
{
search(query: "topic:web-scraping language:python stars:>100", type: REPOSITORY, first: 10) {
repositoryCount
nodes {
... on Repository {
nameWithOwner
stargazerCount
description
}
}
}
}
"""
result = github_graphql(query, "your_token")
print(f"Found {result[data][search][repositoryCount]} repos")
for repo in result["data"]["search"]["nodes"]:
print(f"{repo[stargazerCount]:>5}⭐ {repo[nameWithOwner]}")
Rate Limits
| API | Limit | Per Call |
|---|---|---|
| REST | 5,000 req/hr | 1 endpoint = 1 request |
| GraphQL | 5,000 points/hr | 1 query = 1 point (usually) |
GraphQL uses a point system based on query complexity. Simple queries cost 1 point. Complex nested queries cost more. But you almost always use fewer points than REST calls for the same data.
When to Use GraphQL vs REST
Use GraphQL when:
- You need data from multiple related resources
- You want exactly the fields you need (no over-fetching)
- You're building dashboards or comparison tools
Use REST when:
- Simple single-resource operations (create issue, merge PR)
- You need streaming/webhooks
- You're using GitHub Actions (REST is simpler in scripts)
Explore the Schema
GitHub's GraphQL Explorer lets you build queries with autocomplete:
https://docs.github.com/en/graphql/overview/explorer
I build developer tools and data pipelines. More tutorials on GitHub.
More from me: 10 Dev Tools I Use Daily | 77 Scrapers on a Schedule | 150+ Free APIs
Top comments (0)