SlideShare a Scribd company logo
Better APIs
with GraphQL
Josh Price
github.com/joshprice
@joshprice
Agenda
• Understand GraphQL and why you'd use it
• Build a simple schema
• Run queries against the schema
• Understand important GraphQL concepts
• Summarise client options
REST APIs
REST is great
REST is hard
Cargo Cults
Common Problems
Overfetching
Underfetching
Internal APIs have
strong contracts
between
client and server
GraphQL
What is GraphQL?
• Language for defining schemas, types & queries
• Developed by Facebook in 2012
• Used to improve mobile app performance
• Serves 300 billion+ requests per day
Open Source
• Open sourced in July 2015
• Specification
• facebook.github.io/graphql
• Reference Implementation
• github.com/graphql/graphql-js
• Relay released in August 2015
GraphQL Server Implementations
• JavaScript reference
• Ruby / Python / PHP
• Java / Scala (Sangria)
• .NET
• Elixir / Go / Haskell / OCaml
• etc...
GraphQL Misconceptions
• Not really about "graphs"
• A specification for client/server interaction
• Language independent
• Assumes nothing about:
• transport
• message protocol
• data store
Exhibit A: REST API
Fetch user name and friends names with 2 requests
GET /users/1
GET /users/1/friends
or a single request
GET /users/1/friends?include=user.name,friend.name
Exhibit B: GraphQL API
{ "data": {
user(id: 1) { "user": {
name "name": "Josh",
friends(first: 1) { "friends": [{
name "name": "James"
} }]
} }
} }
Better
Mental
Model
Strongly
typed
Single
Endpoint
Single
Unambiguous
Query
Consumer
Driven
Contracts
Less
Versioning
Self
Documenting
Performance
Let's build our
first Schema
Query and Mutation Roots
type Query {
me: User
user(id: Int): User
}
type Mutation {
createPost(title: String!): Post
createComment(message: String!): Comment
}
Object Types and Enums
type User {
name: String
profilePicture(size: Int = 50): ProfilePicture
friends(first: Int, orderBy: FriendOrder): [User]
}
enum FriendOrder { FIRST_NAME, LAST_NAME, IMPORTANCE }
More Types
type ProfilePicture {
width: Int
height: Int
url: String
}
type Event {
name: String
attendees(first: Int): [User]
}
Simplest Query
{
me {
name
}
}
{
"data": {
"me": {
"name": "Josh Price"
}
}
}
Deeply Nested Query
{ {
me { "data": {
name "name": "Josh Price",
profilePicture { "profilePicture": {
url "url": "http://cdn/josh_50x50.png"
} },
friends(first: 1) { "friends": [{
name "name": "James Sadler"
} }],
events(first: 1) { "events": [{
name "name": "Afterparty!",
attendees(first: 1) { "attendees": [{
name "name": "Jenny Savage"
} }]
} }]
} }
} }
How do we fetch
data?
Resolvers
• Your own functions
• Could use in memory data
• Call any data store
• Proxy REST APIs
• Call existing services
• GraphQL doesn't care
• Resolver "Middleware" is possible (Auth, Logging, etc)
User Type with JS Resolvers
new GraphQLObject({
type: "User",
fields: {
name(user) {
return user.name
},
profilePicture(user, {size}) {
return getProfilePicForUser(user, size);
},
friends(user) {
return user.friendIDs.map(id => getUser(id));
}
}
});
Mutations Modify Data
mutation {
acceptFriendRequest(userId: 345124) {
user {
friends { count }
}
}
}
mutation {
rsvpToEvent(eventId: 134624, status: ATTENDING) {
event {
invitees { count }
attendees { count }
}
}
}
Setup GraphQL Express
import { Schema } from './schema.js';
import graphqlHTTP from 'express-graphql';
import express from 'express';
const app = express();
app.get('/', function(req, res) {
res.redirect('/graphql');
});
app.use('/graphql', graphqlHTTP({ schema: Schema, graphiql: true }));
app.listen(3000);
Relay
• Each view component declares query fragment
• Relay batches all data req'ts for render tree
• Sends single query
• Handles caching using global IDs
• Relies on schema conventions for metadata
Client-Side Alternatives
• ApolloStack Client
• React + Native
• Angular 2
• Redux support
• Lokka
• Simple
Gotchas
• Arbitrary Queries
• Could be slow if deeply nested (friends of friends...)
• Complexity analysis
• Query depth
• Batching resolvers
• Data Loader (JS)
• GraphQL Batch (Ruby)
When to use?
• Use for internal APIs first, or limited external use
• Improve mobile (and desktop performance)
• Github has exposed their API externally
• Be careful exposing this to the world!
• Don't allow arbitrary queries from unknown clients
GraphQL Ecosystem
Evolving Quickly
GraphQL Backend as a Service
• reindex.io
• graph.cool
• scaphold.io
Future - GraphQL Spec
• Push: Apps should reflect current state of world
• Subscriptions + Reactive Backend + RethinkDB
• Defer
• Stream
• Live queries
• GraphQL CATS
Subscriptions
subscription {
createCommentSubscribe(storyId: $id) {
comment {
...FBCommentFragment
}
}
}
Warning!
Experimental
Defer Directive
{ {
feed { "feed": {
stories { "stories": [{
author { name } "author": { "name": "Lee Byron" },
title "title": "GraphQL is the Future"
comments @defer { }, {
author { name } "author": { "name": "Josh Price" },
comment "title": "REST is old school"
} }]
} }
} }
}
Defer - Comments arrive
{ {
feed { "path": ["feed", "stories", 0, "comment"],
stories { "data": [{
author { name } "author": { "name": "Joe Bloggs" },
title "comment": "That blew my mind!"
comments @defer { }, {
author { name } "author": { "name": "Jenny Savage" },
comment "comment": "I love it"
} }]
} }
}
}
Stream Directive
{ {
feed { "feed": {
stories @stream { "stories": []
author { name } }
title }
comments @defer {
author { name }
comment
}
}
}
}
Stream - First Story
{ {
feed { "path": ["feed", "stories", 0],
stories @stream { "data": [{
author { name } "author": { "name": "Joe Bloggs" },
title "title": "That blew my mind!"
comments @defer { }]
author { name } }
comment
}
}
}
}
Live Directive
{ {
feed { "feed": {
stories { "stories": [{
author { name } "author": { "name": "Lee Byron" },
title "title": "GraphQL is the Future",
likeCount @live "likeCount": 9
} }]
} }
} }
Live - Likes update on backend
{ {
feed { "path": ["feed", "stories", 0, "likeCount"],
stories { "data": 10
author { name } }
title
likeCount @live
}
}
}
Resources
• graphql.org
• Github
• graphql/graphql-js
• graphql/express-graphql
• Steve Luscher talk Zero to GraphQL
• Awesome GraphQL (chentsulin/awesome-graphql)
Questions?
Thanks!

More Related Content

What's hot (20)

PDF
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
luisw19
 
PDF
Introduction to GraphQL
Sangeeta Ashrit
 
PPT
Graphql presentation
Vibhor Grover
 
PPTX
Introduction to graphQL
Muhilvarnan V
 
PPTX
Introduction to GraphQL
Bhargav Anadkat
 
PDF
React & GraphQL
Nikolas Burk
 
PPTX
Intro GraphQL
Simona Cotin
 
PDF
GraphQL
Cédric GILLET
 
PPTX
Introduction to GraphQL Presentation.pptx
Knoldus Inc.
 
PPTX
GraphQL API Gateway and microservices
Mohammed Shaban
 
PDF
Graphql
Niv Ben David
 
PDF
How to GraphQL: React Apollo
Tomasz Bak
 
PDF
GraphQL Fundamentals
Virbhadra Ankalkote
 
PDF
GraphQL vs REST
GreeceJS
 
PDF
API for Beginners
Gustavo De Vita
 
PPTX
Rest API
Rohana K Amarakoon
 
PDF
Spring GraphQL
VMware Tanzu
 
PDF
REST API and CRUD
Prem Sanil
 
PDF
The Apollo and GraphQL Stack
Sashko Stubailo
 
PDF
REST APIs with Spring
Joshua Long
 
GraphQL as an alternative approach to REST (as presented at Java2Days/CodeMon...
luisw19
 
Introduction to GraphQL
Sangeeta Ashrit
 
Graphql presentation
Vibhor Grover
 
Introduction to graphQL
Muhilvarnan V
 
Introduction to GraphQL
Bhargav Anadkat
 
React & GraphQL
Nikolas Burk
 
Intro GraphQL
Simona Cotin
 
Introduction to GraphQL Presentation.pptx
Knoldus Inc.
 
GraphQL API Gateway and microservices
Mohammed Shaban
 
Graphql
Niv Ben David
 
How to GraphQL: React Apollo
Tomasz Bak
 
GraphQL Fundamentals
Virbhadra Ankalkote
 
GraphQL vs REST
GreeceJS
 
API for Beginners
Gustavo De Vita
 
Spring GraphQL
VMware Tanzu
 
REST API and CRUD
Prem Sanil
 
The Apollo and GraphQL Stack
Sashko Stubailo
 
REST APIs with Spring
Joshua Long
 

Viewers also liked (18)

PDF
GraphQL Story: Intro To GraphQL
Riza Fahmi
 
PDF
GraphQL in an Age of REST
Yos Riady
 
PDF
Introduction to GraphQL
Brainhub
 
PPT
Enterprise API deployment best practice
Sanjay Roy
 
PDF
API Introduction - API Management Workshop Munich from Ronnie Mitra
CA API Management
 
PPTX
API Athens Meetup - API standards 25-6-2014
Michael Petychakis
 
PDF
Best Practice in API Design
Lorna Mitchell
 
PDF
Migration microservices to GraphQL
Roman Krivtsov
 
PDF
Vue JS Intro
Muhammad Rizki Rijal
 
PDF
Javascript MVVM with Vue.JS
Eueung Mulyana
 
PDF
Enjoy the vue.js
TechExeter
 
PDF
Why Vue.js?
Jonathan Goode
 
ODP
An Introduction to Vuejs
Paddy Lock
 
PDF
Vue.js for beginners
Julio Bitencourt
 
PPT
Groovier testing with Spock
Robert Fletcher
 
PPTX
Another API-Blueprint, RAML and Swagger Comparison
SmartBear
 
PPTX
API Athens Meetup - API standards 22.03.2016
Ivan Goncharov
 
PPTX
Enhance existing REST APIs (e.g. Facebook Graph API) with code completion us...
johannes_fiala
 
GraphQL Story: Intro To GraphQL
Riza Fahmi
 
GraphQL in an Age of REST
Yos Riady
 
Introduction to GraphQL
Brainhub
 
Enterprise API deployment best practice
Sanjay Roy
 
API Introduction - API Management Workshop Munich from Ronnie Mitra
CA API Management
 
API Athens Meetup - API standards 25-6-2014
Michael Petychakis
 
Best Practice in API Design
Lorna Mitchell
 
Migration microservices to GraphQL
Roman Krivtsov
 
Vue JS Intro
Muhammad Rizki Rijal
 
Javascript MVVM with Vue.JS
Eueung Mulyana
 
Enjoy the vue.js
TechExeter
 
Why Vue.js?
Jonathan Goode
 
An Introduction to Vuejs
Paddy Lock
 
Vue.js for beginners
Julio Bitencourt
 
Groovier testing with Spock
Robert Fletcher
 
Another API-Blueprint, RAML and Swagger Comparison
SmartBear
 
API Athens Meetup - API standards 22.03.2016
Ivan Goncharov
 
Enhance existing REST APIs (e.g. Facebook Graph API) with code completion us...
johannes_fiala
 
Ad

Similar to Better APIs with GraphQL (20)

PDF
Overview of GraphQL & Clients
Pokai Chang
 
PDF
Graphql usage
Valentin Buryakov
 
PDF
GraphQL + relay
Cédric GILLET
 
PPTX
GraphQL API Crafts presentation
Sudheer J
 
PDF
GraphQL and Relay Modern
Carmel JavaScript Roundabout
 
PDF
GraphQL And Relay Modern
Brad Pillow
 
PDF
GraphQL And Relay Modern
Brad Pillow
 
PDF
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
Rob Crowley
 
PDF
GraphQL with .NET Core Microservices.pdf
Knoldus Inc.
 
PDF
The Serverless GraphQL Backend Architecture
Nikolas Burk
 
PDF
Let's start GraphQL: structure, behavior, and architecture
Andrii Gakhov
 
PDF
GraphQL & Prisma from Scratch
Nikolas Burk
 
PDF
Why UI developers love GraphQL
Sashko Stubailo
 
PDF
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/Meteor
Jon Wong
 
DOCX
GraphQL Advanced Concepts A Comprehensive Guide.docx
ssuser5583681
 
PDF
GraphQL Meetup Bangkok 4.0
Tobias Meixner
 
PDF
Introduction to GraphQL for beginners
Martin Pham
 
PDF
REST to GraphQL migration: Pros, cons and gotchas
Alexey Ivanov
 
PDF
GraphQL: The Missing Link Between Frontend and Backend Devs
Sashko Stubailo
 
PDF
GraphQL - A love story
bwullems
 
Overview of GraphQL & Clients
Pokai Chang
 
Graphql usage
Valentin Buryakov
 
GraphQL + relay
Cédric GILLET
 
GraphQL API Crafts presentation
Sudheer J
 
GraphQL and Relay Modern
Carmel JavaScript Roundabout
 
GraphQL And Relay Modern
Brad Pillow
 
GraphQL And Relay Modern
Brad Pillow
 
GraphQL - A query language to empower your API consumers (NDC Sydney 2017)
Rob Crowley
 
GraphQL with .NET Core Microservices.pdf
Knoldus Inc.
 
The Serverless GraphQL Backend Architecture
Nikolas Burk
 
Let's start GraphQL: structure, behavior, and architecture
Andrii Gakhov
 
GraphQL & Prisma from Scratch
Nikolas Burk
 
Why UI developers love GraphQL
Sashko Stubailo
 
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/Meteor
Jon Wong
 
GraphQL Advanced Concepts A Comprehensive Guide.docx
ssuser5583681
 
GraphQL Meetup Bangkok 4.0
Tobias Meixner
 
Introduction to GraphQL for beginners
Martin Pham
 
REST to GraphQL migration: Pros, cons and gotchas
Alexey Ivanov
 
GraphQL: The Missing Link Between Frontend and Backend Devs
Sashko Stubailo
 
GraphQL - A love story
bwullems
 
Ad

Recently uploaded (20)

PDF
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
PPTX
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PPTX
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
PDF
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PPTX
Milwaukee Marketo User Group - Summer Road Trip: Mapping and Personalizing Yo...
bbedford2
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PDF
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PPTX
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
PDF
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PPTX
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
MiniTool Power Data Recovery 8.8 With Crack New Latest 2025
bashirkhan333g
 
Comprehensive Risk Assessment Module for Smarter Risk Management
EHA Soft Solutions
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
Milwaukee Marketo User Group - Summer Road Trip: Mapping and Personalizing Yo...
bbedford2
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
[Solution] Why Choose the VeryPDF DRM Protector Custom-Built Solution for You...
Lingwen1998
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 
Tally software_Introduction_Presentation
AditiBansal54083
 
Homogeneity of Variance Test Options IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 

Better APIs with GraphQL

  • 1. Better APIs with GraphQL Josh Price github.com/joshprice @joshprice
  • 2. Agenda • Understand GraphQL and why you'd use it • Build a simple schema • Run queries against the schema • Understand important GraphQL concepts • Summarise client options
  • 8. Internal APIs have strong contracts between client and server
  • 10. What is GraphQL? • Language for defining schemas, types & queries • Developed by Facebook in 2012 • Used to improve mobile app performance • Serves 300 billion+ requests per day
  • 11. Open Source • Open sourced in July 2015 • Specification • facebook.github.io/graphql • Reference Implementation • github.com/graphql/graphql-js • Relay released in August 2015
  • 12. GraphQL Server Implementations • JavaScript reference • Ruby / Python / PHP • Java / Scala (Sangria) • .NET • Elixir / Go / Haskell / OCaml • etc...
  • 13. GraphQL Misconceptions • Not really about "graphs" • A specification for client/server interaction • Language independent • Assumes nothing about: • transport • message protocol • data store
  • 14. Exhibit A: REST API Fetch user name and friends names with 2 requests GET /users/1 GET /users/1/friends or a single request GET /users/1/friends?include=user.name,friend.name
  • 15. Exhibit B: GraphQL API { "data": { user(id: 1) { "user": { name "name": "Josh", friends(first: 1) { "friends": [{ name "name": "James" } }] } } } }
  • 25. Query and Mutation Roots type Query { me: User user(id: Int): User } type Mutation { createPost(title: String!): Post createComment(message: String!): Comment }
  • 26. Object Types and Enums type User { name: String profilePicture(size: Int = 50): ProfilePicture friends(first: Int, orderBy: FriendOrder): [User] } enum FriendOrder { FIRST_NAME, LAST_NAME, IMPORTANCE }
  • 27. More Types type ProfilePicture { width: Int height: Int url: String } type Event { name: String attendees(first: Int): [User] }
  • 28. Simplest Query { me { name } } { "data": { "me": { "name": "Josh Price" } } }
  • 29. Deeply Nested Query { { me { "data": { name "name": "Josh Price", profilePicture { "profilePicture": { url "url": "http://cdn/josh_50x50.png" } }, friends(first: 1) { "friends": [{ name "name": "James Sadler" } }], events(first: 1) { "events": [{ name "name": "Afterparty!", attendees(first: 1) { "attendees": [{ name "name": "Jenny Savage" } }] } }] } } } }
  • 30. How do we fetch data?
  • 31. Resolvers • Your own functions • Could use in memory data • Call any data store • Proxy REST APIs • Call existing services • GraphQL doesn't care • Resolver "Middleware" is possible (Auth, Logging, etc)
  • 32. User Type with JS Resolvers new GraphQLObject({ type: "User", fields: { name(user) { return user.name }, profilePicture(user, {size}) { return getProfilePicForUser(user, size); }, friends(user) { return user.friendIDs.map(id => getUser(id)); } } });
  • 33. Mutations Modify Data mutation { acceptFriendRequest(userId: 345124) { user { friends { count } } } } mutation { rsvpToEvent(eventId: 134624, status: ATTENDING) { event { invitees { count } attendees { count } } } }
  • 34. Setup GraphQL Express import { Schema } from './schema.js'; import graphqlHTTP from 'express-graphql'; import express from 'express'; const app = express(); app.get('/', function(req, res) { res.redirect('/graphql'); }); app.use('/graphql', graphqlHTTP({ schema: Schema, graphiql: true })); app.listen(3000);
  • 35. Relay • Each view component declares query fragment • Relay batches all data req'ts for render tree • Sends single query • Handles caching using global IDs • Relies on schema conventions for metadata
  • 36. Client-Side Alternatives • ApolloStack Client • React + Native • Angular 2 • Redux support • Lokka • Simple
  • 37. Gotchas • Arbitrary Queries • Could be slow if deeply nested (friends of friends...) • Complexity analysis • Query depth • Batching resolvers • Data Loader (JS) • GraphQL Batch (Ruby)
  • 38. When to use? • Use for internal APIs first, or limited external use • Improve mobile (and desktop performance) • Github has exposed their API externally • Be careful exposing this to the world! • Don't allow arbitrary queries from unknown clients
  • 40. GraphQL Backend as a Service • reindex.io • graph.cool • scaphold.io
  • 41. Future - GraphQL Spec • Push: Apps should reflect current state of world • Subscriptions + Reactive Backend + RethinkDB • Defer • Stream • Live queries • GraphQL CATS
  • 44. Defer Directive { { feed { "feed": { stories { "stories": [{ author { name } "author": { "name": "Lee Byron" }, title "title": "GraphQL is the Future" comments @defer { }, { author { name } "author": { "name": "Josh Price" }, comment "title": "REST is old school" } }] } } } } }
  • 45. Defer - Comments arrive { { feed { "path": ["feed", "stories", 0, "comment"], stories { "data": [{ author { name } "author": { "name": "Joe Bloggs" }, title "comment": "That blew my mind!" comments @defer { }, { author { name } "author": { "name": "Jenny Savage" }, comment "comment": "I love it" } }] } } } }
  • 46. Stream Directive { { feed { "feed": { stories @stream { "stories": [] author { name } } title } comments @defer { author { name } comment } } } }
  • 47. Stream - First Story { { feed { "path": ["feed", "stories", 0], stories @stream { "data": [{ author { name } "author": { "name": "Joe Bloggs" }, title "title": "That blew my mind!" comments @defer { }] author { name } } comment } } } }
  • 48. Live Directive { { feed { "feed": { stories { "stories": [{ author { name } "author": { "name": "Lee Byron" }, title "title": "GraphQL is the Future", likeCount @live "likeCount": 9 } }] } } } }
  • 49. Live - Likes update on backend { { feed { "path": ["feed", "stories", 0, "likeCount"], stories { "data": 10 author { name } } title likeCount @live } } }
  • 50. Resources • graphql.org • Github • graphql/graphql-js • graphql/express-graphql • Steve Luscher talk Zero to GraphQL • Awesome GraphQL (chentsulin/awesome-graphql)