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
GraphQL: A Horizontal Platform
Search
Dan Schafer
November 17, 2015
Programming
2
220
GraphQL: A Horizontal Platform
GraphQL: A Horizontal Platform
Dan Schafer
Taipei, 17-18 November 2015
Singapore, 21 November 2015
Dan Schafer
November 17, 2015
Tweet
Share
More Decks by Dan Schafer
See All by Dan Schafer
The Prehistory of GraphQL
dschafer
1
320
GraphQL: Client-Driven Development
dschafer
0
330
GraphQL at Facebook
dschafer
0
190
Efficient Data Fetching with GraphQL and Relay
dschafer
3
350
Other Decks in Programming
See All in Programming
Package Traits
ikesyo
1
200
VisionProで部屋の明るさを反映させるシェーダーを作った話
segur
0
100
EC2からECSへ 念願のコンテナ移行と巨大レガシーPHPアプリケーションの再構築
sumiyae
3
580
令和7年版 あなたが使ってよいフロントエンド機能とは
mugi_uno
10
5k
Lookerは可視化だけじゃない。UIコンポーネントもあるんだ!
ymd65536
1
130
chibiccをCILに移植した結果 (NGK2025S版)
kekyo
PRO
0
110
アクターシステムに頼らずEvent Sourcingする方法について
j5ik2o
6
700
선언형 UI에서의 상태관리
l2hyunwoo
0
270
asdf-ecspresso作って 友達が増えた話 / Fujiwara Tech Conference 2025
koluku
0
1.3k
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
420
traP の部内 ISUCON とそれを支えるポータル / PISCON Portal
ikura_hamu
0
180
watsonx.ai Dojo #6 継続的なAIアプリ開発と展開
oniak3ibm
PRO
0
170
Featured
See All Featured
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
Site-Speed That Sticks
csswizardry
2
250
KATA
mclloyd
29
14k
Fireside Chat
paigeccino
34
3.1k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
570
Large-scale JavaScript Application Architecture
addyosmani
510
110k
A Tale of Four Properties
chriscoyier
157
23k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.3k
The Cost Of JavaScript in 2023
addyosmani
46
7.2k
How to train your dragon (web standard)
notwaldorf
89
5.8k
The Power of CSS Pseudo Elements
geoffreycrofte
74
5.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Transcript
None
GraphQL: A Horizontal Platform Dan Schafer Software Engineer
Facebook Mobile Circa 2011
HTML 5 in a Native View
Mobile Afterthought to Mobile First
Truly Native!
HTML5 App Data Services Web Server HTML
Native App Data Services App Server Data
RESTful API
None
Join-tables http://url.api/reso
None
GraphQL
Over 260 Billion served per day
What is GraphQL?
{ me { name } }
{ "me": { "name": "Daniel Schafer" } } { me
{ name } }
{ "user": { "name": "Daniel Schafer" } } { user(id:
1031) { name } }
{ me { name, profilePicture { width, height, url }
} }
{ "me": { "name": "Daniel Schafer", "profilePicture": { "width": 50,
"height": 50, "url": "https://cdn/50.jpg" } } } { me { name, profilePicture { width, height, url } } }
{ me { name, friends { name } } }
{ "me": { "name": "Daniel Schafer", "friends": [ { "name": "Lee Byron" }, { "name": "Nick Schrock" }, { "name": "Alex Langenfeld" },
{ me { name, friends { name, events { name
} } } } { "me": { "name": "Daniel Schafer", "friends": [ { "name": "Lee Byron", "events": [ { "name": "GraphQL Team Dinner" }, { "name": "Bow Tie Conference" }, ] }
GraphQL Core Principles
Mental Model for Product Developers
Type System
{ me { name, friends(orderby: IMPORTANCE, first: 1) { name,
events(first: 1) { name } } } }
{ me { name, friends(orderby: IMPORTANCE, first: 1) { name,
events(first: 1) { name } } } } type Query { me: User user(id: Int): User } { me }
type User { name: String friends(first: Int, orderby: FriendOrderEnum): [User]
events(first: Int): [Event] } enum FriendOrderEnum { FIRST_NAME, IMPORTANCE } { me { name, friends(orderby: IMPORTANCE, first: 1) { name, events(first: 1) { name } } } } { name, friends(orderby: IMPORTANCE, first: 1) }
type User { name: String profilePicture(size: Int = 50): ProfilePicture
friends(first: Int, orderby: FriendOrderEnum): [User] events(first: Int): [Event] } { me { name, friends(orderby: IMPORTANCE, first: 1) { name, events(first: 1) { name } } } } { name, events(first: 1) }
type Event { name: String attendees(first: Int): [User] } {
me { name, friends(orderby: IMPORTANCE, first: 1) { name, events(first: 1) { name } } } } { name }
Models Views Here's your 123 model CLIENT Model: 123, plz
APP SERVER
Models Models v2 Views v2 Views Here's your 123 v2
model CLIENT Model: 123, v2, plz APP SERVER
Models Models v2 Models v3 Views v3 Views v2 Views
Here's your 123 v3 model CLIENT Model: 123, v3, plz APP SERVER
Models v2 Models v3 Models v4 Views v4 Views v3
Views v2 CLIENT Here's your 123 v4 model APP SERVER Model: 123, v4, plz
Capabilities Requirements CLIENT APP SERVER
Type System Views Models This data shape, plz Here's your
specific data CLIENT APP SERVER
Views v2 Views Models Models v2 This data shape, plz
Here's your specific data CLIENT APP SERVER Type System
Views v3 Views v2 Views Models Models v2 Models v3
This data shape, plz Here's your specific data CLIENT APP SERVER Type System
iOS Feed Android Feed Ads Manager iPad Pages iOS Messenger
Facebook Lite
Composition
{ me { name friends { } } } name
events { name }
fragment friendFragment on User { } { me { name
friends { ...friendFragment } } } name events { name }
Relay
TimelineView HeaderView AboutView
TimelineView HeaderView AboutView
fragment timelineFragment on User { ...headerFragment ...aboutFragment } fragment headerFragment
on User { name profilePicture coverPhoto } fragment aboutFragment on User { currentWork previousWork school }
Backed by arbitrary code
Feed Ranking & Storage
User DB Feed Ranking & Storage
Feed Ranking & Storage User DB Link & Image Cache
User DB Feed Ranking & Storage
Existing Application Code Link & Image Cache User DB Feed
Ranking & Storage
GraphQL Existing Application Code Link & Image Cache User DB
Feed Ranking & Storage
GraphQL is not a storage engine
GraphQL queries operate over arbitrary code
GraphQL queries can operate over your existing code
GraphQL Type Your Code
type User { profilePicture(size: Int = 50): ProfilePicture } friends:
[User]
type User { profilePicture(size: Int = 50): ProfilePicture } friends:
[User]
// type User { { // profilePicture(size: Int = 50):
ProfilePicture profilePicture(user, {size}) { return user.profilePicture; }, // friends: [User] friends(user) { return user.friendIDs.map(id => promiseUser(id)); } }
// type User { { // profilePicture(size: Int = 50):
ProfilePicture profilePicture(user, {size}) { return user.profilePicture; }, // friends: [User] friends(user) { return user.friendIDs.map(id => promiseUser(id)); } } profilePicture(user, {size}) { return user.profilePicture; }
// type User { { // profilePicture(size: Int = 50):
ProfilePicture profilePicture(user, {size}) { return getProfilePicForUser(user, size); }, // friends: [User] friends(user) { return user.friendIDs.map(id => promiseUser(id)); } } profilePicture(user, {size}) { return getProfilePicForUser(user, size); }
// type User { { // profilePicture(size: Int = 50):
ProfilePicture profilePicture(user, {size}) { return getProfilePicForUser(user, size); }, // friends: [User] friends(user) { return user.friendIDs.map(id => promiseUser(id)); } } friends(user) { return user.friendIDs.map(id => promiseUser(id)); }
Type system on the Client
{ __schema { queryType { name } types { name
fields { name, type { name, } } } } }
Introspection A platform for building tools
Documentation (screenshot of doc explorer)
{ me { name, profilePicture { width, height, url }
} } @interface GraphQLUser : NSObject { - (NSString *)name; - (GraphQLPic *)profilePicture; } @interface GraphQLProfilePicture - (NSNumber *)width; - (NSNumber *)height; - (NSString *)url; } Code Generation
Mutations
{ user(id: 1572451031) { name, profilePicture { width, height, url
} } }
{ user(id: 1572451031) { name, profilePicture { width, height, url
} } }
query { user(id: 1572451031) { name, profilePicture { width, height,
url } } }
mutation { }
mutation { likeStory { } }
mutation { likeStory(storyId: 37000641) { } }
mutation { likeStory(storyId: 37000641) { story { likers { count
} doesViewerLike } } }
mutation { createComment( storyId: 37000641 text: “Hello” ) { comment
{ createTime } } } mutation { updateComment( commentId: 37000641 newText: “Hello” ) { comment { text } } }
mutation { acceptFriendRequest( userId: 37000641 ) { user { friends
{ count } } } } mutation { eventRsvp( eventId: 37000641 status: ATTENDING ) { event { invitees { count } attendees { count } } } }
From REST to GraphQL
None
None
None
None
SWAPI in GraphQL
DEMO
Something Changed!
None
GraphQL queries operate over arbitrary code
None
None
REST Polyfill Structure GraphQL Core App Server Type Definitions GraphQL
Server REST Server
Direct Access Structure GraphQL Core App Server Type Definitions GraphQL
Server
GraphQL
None
None
RFC specification graphql-js graphiql
express-graphql libgraphqlparser swapi-graphql
External Projects!
graphql-ruby graphql-java sangria (scala) reindex.io Financial Times
graphql.org
Open Source Projects etc
Whole Greater Than Sum of The Parts
Mobile Revolution Giant Leap Forward for Consumers A Big Step
Backwards for Developers and Product Organizations
Open Standards Proprietary Platforms Instant Distribution Installed Binaries Fast Iteration
Compile Cycles Unified Teams Platform-aware Teams
The right tools and software can change the landscape
None
React is Opinionated • Functional Programming • Immutable Data Structures
• Declarative APIs • Rethinking Best Practices™
React Web React
iOS React Native Android … React Native Web React
A Horizontal, Opinionated Platform Unifying Software, Abstractions, and Tools Proprietary
Capabilities
Learn Once, Write Anywhere Write Once, Run Anywhere
GraphQL GraphQL JS Ruby Hack … SQL Mongo Rethink …
Relay
Ads Manager
None