Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Launching GitHub's Public GraphQL API
Brooks Swinnerton
May 21, 2017
Technology
2
460
Launching GitHub's Public GraphQL API
Brooks Swinnerton
May 21, 2017
Tweet
Share
More Decks by Brooks Swinnerton
See All by Brooks Swinnerton
Building GitHub Integrations with Webhooks and REST
bswinnerton
2
130
Launching GitHub's GraphQL API
bswinnerton
4
490
Optimizing APIs for Consumers with GraphQL
bswinnerton
2
360
GitHub GraphQL API
bswinnerton
4
94
GraphQL for Rubyists
bswinnerton
0
240
The Road To Code: Ruby
bswinnerton
0
58
The history of Vim
bswinnerton
0
88
Other Decks in Technology
See All in Technology
re:Inventで発表があったIoT事例の紹介と考察
kizawa2020
0
190
PCI DSS に準拠したシステム開発
yutadayo
0
310
USB PD で迎える AC アダプター大統一時代
puhitaku
2
1.9k
20230123_FinJAWS
takuyay0ne
0
120
開発者と協働できるメトリクスダッシュボードを作ろう!/SRE Lounge 2023
lmi
3
500
Google Cloud Workflows: API automation, patterns and best practices
glaforge
0
100
OpenShiftのリリースノートを整理してみた
loftkun
2
400
Multi-Cloud Gatewayでデータを統治せよ!/ Data Federation with MCG
tutsunom
1
300
OVN-Kubernetes-Introduction-ja-2023-01-27.pdf
orimanabu
1
400
Deep dive in Reserved Instance ~脳死推奨量購入からの脱却~
kzkmaeda
0
540
FlexScan HD2452Wの 後継を探して
tring
0
6.4k
Bill One 開発エンジニア 紹介資料
sansantech
PRO
0
120
Featured
See All Featured
Mobile First: as difficult as doing things right
swwweet
213
7.8k
Practical Orchestrator
shlominoach
178
8.9k
Building a Scalable Design System with Sketch
lauravandoore
451
31k
In The Pink: A Labor of Love
frogandcode
132
21k
Unsuck your backbone
ammeep
659
56k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
109
16k
Raft: Consensus for Rubyists
vanstee
130
5.7k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
29
7.9k
How To Stay Up To Date on Web Technology
chriscoyier
779
250k
Build The Right Thing And Hit Your Dates
maggiecrowley
22
1.4k
JazzCon 2018 Closing Keynote - Leadership for the Reluctant Leader
reverentgeek
175
9.1k
Testing 201, or: Great Expectations
jmmastey
25
5.7k
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