Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Launching GitHub's Public GraphQL API
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Brooks Swinnerton
May 21, 2017
Technology
590
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Launching GitHub's Public GraphQL API
Brooks Swinnerton
May 21, 2017
More Decks by Brooks Swinnerton
See All by Brooks Swinnerton
Building GitHub Integrations with Webhooks and REST
bswinnerton
1
190
Launching GitHub's GraphQL API
bswinnerton
4
530
Optimizing APIs for Consumers with GraphQL
bswinnerton
2
460
GitHub GraphQL API
bswinnerton
4
160
GraphQL for Rubyists
bswinnerton
0
330
The Road To Code: Ruby
bswinnerton
0
120
The history of Vim
bswinnerton
0
170
Other Decks in Technology
See All in Technology
Oracle Cloud Network Path Analyzerを試してみた/I Tried Out Oracle Cloud Network Path Analyzer
masakiokuda
1
110
山手線を徒歩で一周してわかった、 位置情報アプリは「足」が最強のデバッガー
hinakko
0
180
AIエージェントの自己改善をどう設計するか / How to Design Self-Improvement for AI Agents
22mi
25
17k
現場で役立つ技術負債の効果的な返済方法
masuda220
PRO
9
5k
人間はどの意思決定を手放せるのか
kawasima
15
7.9k
AIを活用するために決めた "やらないこと" - 価値に注目する / Not betting on AI
soudai
PRO
3
570
Making AI Agents Safe and Fast- Jev, Obsidian, and the Meta-Harness
x5gtrn
PRO
0
110
Genieを崇めよ
kameitomohiro
0
170
LLMに渡さなかった仕事
nanaism
0
1.3k
負債のメタファと2026年 / Debt Metaphor in Agentic Engineering Age 202609 Edition
twada
PRO
10
4.8k
Claude Codeを「使うほど育つ」AI秘書にするノウハウ
minorun365
PRO
33
30k
Vibe Coding で作ったプロダクトをどう安全に動かすか / How to Safely Run Products Built with Vibe Coding
glidenote
0
460
Featured
See All Featured
Odyssey Design
rkendrick25
PRO
2
810
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
900
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
[SF Ruby Conf 2025] Rails X
palkan
3
1.4k
Writing Fast Ruby
sferik
630
63k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
670
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.3k
Design in an AI World
tapps
1
320
Transcript
+ a
Hi, I’m Brooks
I work at !
let’s talk about launching the GitHub GraphQL API
How our GraphQL API came to be
March 20th, 2016 proposal submitted
we had dreams of APIv4
multiple resources in one roundtrip
schema introspection
April 6th, 2016 proof of concept done
{ current_user { login repositories(affiliation: "owner") { id name }
} }
April 12th, 2016 New team created
September 14th, 2016 early access
Today >100 million queries/day
We learned some things along the way
Tooling
documentation
https://github.com/gjtorikian/graphql-docs
GraphiQL all-in-one
"but we’re going to need a Ruby client"
github/graphql-client
objects in exchange for a query
collocate our queries with our views
but in Rails
query profiling
query { repository(owner:"rails", name:"rails") { viewerHasStarred } }
{ "data": { "repository": { "viewerHasStarred": false } }, "extensions":
{ "totalDuration": 42.06737782806158, "trackedAssociations": {}, "profiling": { "Repository:viewerHasStarred": { "type": "Boolean!", "sql": [ { "duration": 2.07, "sql": "SELECT 1 AS one FROM `repositories` INNER JOIN `stars` ON `repositories`.`id` = `stars`.`starrable_id` WHERE `stars`.`user_id` = 934497 AND `stars`.`starrable_type` = 'Repository' AND `repositories`.`id` = 8514 LIMIT 1 " } ] } } } }
Authorization
reusing the OAuth logic from our REST API
OAuth scopes are granted to a token
token is used to make a request
familiar to our users
less for us to build
Organization = GraphQL::ObjectType.define do name "Organization" accepted_scopes ["read:org", "admin:org"] end
Organization = GraphQL::ObjectType.define do name "Organization" accepted_scopes ["read:org", "admin:org"] end
but with ✨ GraphQL ✨…
we can analyze the query before resolution
query { organization(login:"github") { members { totalCount } } }
query { organization(login:"github") { members { totalCount } } }
Organization = GraphQL::ObjectType.define do name "Organization" accepted_scopes ["read:org", "admin:org"] end
but this isn’t perfect
in some cases you need to perform resolution first
repo vs public_repo
we’ve introduced an authz layer for resolution
Schema design
first off
there’s more than one
one for new & sensitive features
one for everyone else
Organization = GraphQL::ObjectType.define do name "Organization" accepted_scopes ["read:org"] end
Organization = GraphQL::ObjectType.define do name "Organization" accepted_scopes ["read:org"] visibility :public
end
Organization = GraphQL::ObjectType.define do name "Organization" accepted_scopes ["read:org"] visibility :public
end
CoolNewFeature = GraphQL::ObjectType.define do name "CoolNewFeature" accepted_scopes ["repo"] visibility :internal
end
mandatory first/last arguments on connections
query { viewer { repositories(last:30) { edges { node {
name } } } } }
query { viewer { repositories(last:30) { edges { node {
name } } } } }
is/has/can prefix
query { repository(owner:"rails", name:"rails") { isFork hasIssuesEnabled viewerCanAdminister } }
query { repository(owner:"rails", name:"rails") { isFork hasIssuesEnabled viewerCanAdminister } }
avoiding fields that should be types
query { repository(owner:"rails", name:"rails") { ownerLogin } }
query { repository(owner:"rails", name:"rails") { ownerLogin } }
query { repository(owner:"rails",name:"rails") { owner { login } } }
Feature Parity
schema driven development* *stay tuned!
with our REST API
new features were developed for the UI
then staff-shipped
then released
REST API work started after the ship
but, today…
all new features are built with GraphQL
from the start
CoolNewFeature = GraphQL::ObjectType.define do name "CoolNewFeature" accepted_scopes ["repo"] visibility :internal
end
CoolNewFeature = GraphQL::ObjectType.define do name "CoolNewFeature" accepted_scopes ["repo"] visibility :internal
end
CoolNewFeature = GraphQL::ObjectType.define do name "CoolNewFeature" accepted_scopes ["repo"] visibility :public
end
this allows us to build a true public API
this allows us to build a true public API
this allows us to build a true platform
shared between GitHubbers and integrators
but change is scary
GraphQL-backed REST APIs
this works great for new features
but what about legacy features?
GET https://api.github.com/user
enter Scientist
github/scientist
measure data discrepancies
measure the difference in performance
None
Where we’re headed
static analysis of schema during code review
rate limiting
expose global relay IDs in REST API
preview new fields and objects with headers
Thank you @bswinnerton on Twitter & GitHub @brooks on Slack