Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Launching GitHub's Public GraphQL API
Search
Brooks Swinnerton
May 21, 2017
Technology
580
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
170
Launching GitHub's GraphQL API
bswinnerton
4
520
Optimizing APIs for Consumers with GraphQL
bswinnerton
2
450
GitHub GraphQL API
bswinnerton
4
150
GraphQL for Rubyists
bswinnerton
0
320
The Road To Code: Ruby
bswinnerton
0
120
The history of Vim
bswinnerton
0
150
Other Decks in Technology
See All in Technology
しくみを学んで使いこなそう GitHub Copilot app
torumakabe
2
250
実装だけじゃない! CCA-F取得エンジニアが教えるClaude Code開発プロセス活用術
diggymo
2
740
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.4k
Control Planeで育てるBtoB SaaSの認証基盤 - SRE NEXT 2026
pokohide
1
2.4k
SREとQA 二人三脚で進めるSLO運用/sre-qa-slo
sugitak
0
630
壊して学ぶAWS CDK: そのcdk deployで消えるもの、残るもの
k_adachi_01
1
240
kintone の AI コワーカーを、 Anthropic にエージェントを"ホストさせて"作った話 #devkinmeetup
sugimomoto
0
110
AIと共生する開発者プラットフォーム:バクラクのモノレポ×マイクロサービス基盤
sakajunquality
2
3.6k
完全自律ロボットを作りたくて、先に開発を自律させた話(ROS Japan UG #63 LT)
rryz09
0
610
Genie Ontologyは銀の弾丸かを考える / Is Genie Ontology a Silver Bullet?
nttcom
0
310
個人開発で育てる「大規模設計の苗床」 - AI時代の1人開発から始める業務への知識接続 / The Seedbed for Large-Scale Design - From AI-Era Solo Projects to Professional Knowledge
bitkey
PRO
1
250
環境凍結という Toil を倒す -セルフサービス型 Ephemeral テスト環境の 設計と実践
shirouz
1
2.4k
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
880
The Pragmatic Product Professional
lauravandoore
37
7.4k
Documentation Writing (for coders)
carmenintech
77
5.4k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
410
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Raft: Consensus for Rubyists
vanstee
141
7.6k
Building Applications with DynamoDB
mza
96
7.1k
Designing Experiences People Love
moore
143
24k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
RailsConf 2023
tenderlove
30
1.5k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
970
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
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