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
230
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
350
GraphQL: Client-Driven Development
dschafer
0
340
GraphQL at Facebook
dschafer
0
200
Efficient Data Fetching with GraphQL and Relay
dschafer
3
360
Other Decks in Programming
See All in Programming
変化を楽しむエンジニアリング ~ いままでとこれから ~
murajun1978
0
670
なぜ今、Terraformの本を書いたのか? - 著者陣に聞く!『Terraformではじめる実践IaC』登壇資料
fufuhu
4
420
「次に何を学べばいいか分からない」あなたへ──若手エンジニアのための学習地図
panda_program
3
720
Infer入門
riru
4
820
Comparing decimals in Swift Testing
417_72ki
0
160
可変性を制する設計: 構造と振る舞いから考える概念モデリングとその実装
a_suenami
10
1.6k
React は次の10年を生き残れるか:3つのトレンドから考える
oukayuka
41
16k
Flutter로 Gemini와 MCP를 활용한 Agentic App 만들기 - 박제창 2025 I/O Extended Seoul
itsmedreamwalker
0
110
Vibe coding コードレビュー
kinopeee
0
420
Scale out your Claude Code ~自社専用Agentで10xする開発プロセス~
yukukotani
8
1.4k
0から始めるモジュラーモノリス-クリーンなモノリスを目指して
sushi0120
0
250
Workers を定期実行する方法は一つじゃない
rokuosan
0
140
Featured
See All Featured
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
How to Think Like a Performance Engineer
csswizardry
25
1.8k
Building Flexible Design Systems
yeseniaperezcruz
328
39k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Rails Girls Zürich Keynote
gr2m
95
14k
Balancing Empowerment & Direction
lara
1
530
Fireside Chat
paigeccino
38
3.6k
Documentation Writing (for coders)
carmenintech
73
5k
A better future with KSS
kneath
239
17k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
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