$30 off During Our Annual Pro Sale. View Details »
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
240
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
370
GraphQL: Client-Driven Development
dschafer
0
340
GraphQL at Facebook
dschafer
0
200
Efficient Data Fetching with GraphQL and Relay
dschafer
3
370
Other Decks in Programming
See All in Programming
connect-python: convenient protobuf RPC for Python
anuraaga
0
350
Microservices rules: What good looks like
cer
PRO
0
540
TypeScriptで設計する 堅牢さとUXを両立した非同期ワークフローの実現
moeka__c
6
2.9k
目的で駆動する、AI時代のアーキテクチャ設計 / purpose-driven-architecture
minodriven
11
3.9k
配送計画の均等化機能を提供する取り組みについて(⽩⾦鉱業 Meetup Vol.21@六本⽊(数理最適化編))
izu_nori
0
120
大体よく分かるscala.collection.immutable.HashMap ~ Compressed Hash-Array Mapped Prefix-tree (CHAMP) ~
matsu_chara
1
210
AIエンジニアリングのご紹介 / Introduction to AI Engineering
rkaga
2
1.1k
バックエンドエンジニアによる Amebaブログ K8s 基盤への CronJobの導入・運用経験
sunabig
0
130
TVerのWeb内製化 - 開発スピードと品質を両立させるまでの道のり
techtver
PRO
3
1.4k
Microservices Platforms: When Team Topologies Meets Microservices Patterns
cer
PRO
1
910
非同期処理の迷宮を抜ける: 初学者がつまづく構造的な原因
pd1xx
1
570
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
8
18k
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
6.7k
Context Engineering - Making Every Token Count
addyosmani
9
460
BBQ
matthewcrist
89
9.9k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3k
Designing for Performance
lara
610
69k
A better future with KSS
kneath
240
18k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Raft: Consensus for Rubyists
vanstee
140
7.2k
Rebuilding a faster, lazier Slack
samanthasiow
84
9.3k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
1
75
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.2k
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