Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
From REST to GraphQL
Search
Marc-Andre Giroux
September 06, 2016
Programming
1.3k
9
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
From REST to GraphQL
Marc-Andre Giroux
September 06, 2016
More Decks by Marc-Andre Giroux
See All by Marc-Andre Giroux
It Depends - Examining GraphQL Myths & Assumptions
xuorig
0
150
So you Want to Distribute your GraphQL Schema?
xuorig
4
880
So you Want to Distribute your GraphQL Schema?
xuorig
0
700
GraphQL Schema Design @ Scale
xuorig
5
2.2k
Continuous Evolution of GraphQL Schemas @ GitHub
xuorig
3
2.2k
GraphQL à Shopify
xuorig
0
300
Exploring GraphQL
xuorig
0
320
GraphQL @ Shopify
xuorig
6
1.8k
GraphQL on Rails
xuorig
2
410
Other Decks in Programming
See All in Programming
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
370
選挙速報を多くのユーザーへ 届ける Live Activities 設計
hamayokokuririn
0
190
Java 27新機能 / Java 27 new features
kishida
2
190
Heart of Swift Concurrency
koher
0
1.1k
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
5.2k
Simple Storage Service(S3) is not simple
iwatsukayura
0
120
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
520
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
450
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
19
20k
Apple Intelligence を用いた個人情報誤送信防止、及びユーザーリクエスト体験の改善について
yukiny
0
260
Intent as Code
shoppingjaws
6
1.1k
Androidだけじゃない、DroidKaigiで広がった私の技術スタック
akkeylab
0
110
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
510
Ruling the World: When Life Gets Gamed
codingconduct
0
380
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.2k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
42k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Ten Tips & Tricks for a 🌱 transition
stuffmc
1
240
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
270
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
590
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
76k
Transcript
From REST to GraphQL Marc-Andre Giroux @__xuorig__
About me
None
A simple UI component
None
What kind of data is needed?
Cart Product ProductImage
Reusable endpoints (REST)
/carts/1 /products/1 /products/2 /products/3 /product_images/1 /product_images/2 /product_images/3
Too many round trips!
/carts/1?expand=products
/carts/1?fields=products(name, description, price)
/carts/1?fields=products/name,description,price
Custom Endpoints
/cart_with_all_the_stuff_i_need
None
/cart_with_all_the_stuff_i_need /cart_version_2_with_all_the_things /cart_with_products_and_images /cart_with_products_and_images_with_price_and_taxes my_tightly_coupled_custom_endpoint_including_only_the_things_i_need_bla_bla_bla_bla /cart_with_products_and_images_with_price_and_taxes_but_no_description /cart_with_products_and_images_with_price_and_taxes_but_no_description_v2
None
Server Client Updates a view Creates a new view Product
view v2 Product model changes Update endpoints Create new endpoint
GraphQL
What GraphQL is NOT
What GraphQL IS
{ myShop { name } } Field Selection Set
{ myShop { name } } Lexed Parsed Validated Executed
{ “myShop” { “name”: “GitHub” } }
{ myShop { name } }
{ myShop { name } }
None
{ shop(id: 1) { name } }
{ myShop { name location { city address } products(orderby:
POPULARITY) { name price } } }
{ “myShop”: { “name”: “Full Stack Fest Shop” “location” {
“city”: “Barcelona” “address”: “Av. Diagonal 547” } “products”: [{ “name”: “Conference Ticket” “price”: 500000 }, { “name”: “Cool T-Shirt” “price”: 20000 }] } }
Type System
{ myShop { name location { city address } products(orderby:
POPULARITY) { name price } } }
{ myShop { name location { city address } products(orderby:
POPULARITY) { name price } } }
type QueryRoot { myShop: Shop shop(id: Int): Shop }
{ myShop { name location { city address } products(orderby:
POPULARITY) { name price } } }
type Shop { name: String location: Address products(orderby: OrderEnum): [Product]
} enum ProductOrderEnum { PRICE, POPULARITY, ALPHABETICAL }
{ myShop { name location { city address } products(orderby:
POPULARITY) { name price } } }
type Address { city: String address: String }
{ myShop { name location { city address } products(orderby:
POPULARITY) { name price } } }
type Product { name: String price: Int }
Fragments
{ myShop { name location { city address } products(orderby:
POPULARITY) { id name price } } }
None
{ myShop { name location { city address } products(orderby:
POPULARITY) { id name price } } }
fragment productFields on Product { id name price }
{ myShop { name location { city address } products(orderby:
POPULARITY) { ...productFields } } }
query Fragment Fragment Fragment Fragment
Introspection
query { __schema { … } }
Static Validation Code Generation IDE Integration Auto Documentation
None
None
Resolving fields
type Product { name: String price: Int }
ProductType = GraphQL::ObjectType.define do name "Product" description “A product sold
at a shop” # … end
field :name do type types.String resolve -> (obj, args, ctx)
{ obj.name } end
field :price do type types.Int resolve -> (obj, args, ctx)
do obj.subtotal + obj.taxes + obj.shipping_price end end
field :price do type types.Int resolve -> (obj, args, ctx)
do obj.subtotal + obj.taxes + obj.shipping_price end end
POST /graphql
Mutations
mutation { createProduct(name: “Nice Mug”, price: 10000) { id name
} }
Drawbacks and solutions
N+1 Queries
field :image do type ImageType resolve -> (product, args, ctx)
do product.image end end field :products do type [ProductType] resolve -> (shop, args, ctx) do shop.products end end
Product Load (1.0ms) SELECT "products".* FROM "products" WHERE "products"."shop_id" =
… Image Load (0.9ms) SELECT "images".* FROM "images" WHERE "images"."product_id" = … Image Load (0.2ms) SELECT "images".* FROM "images" WHERE "images"."product_id" = … Image Load (0.1ms) SELECT "images".* FROM "images" WHERE "images"."product_id" = …
Solution: Batching + Caching
field :image do type ImageType resolve -> (product, args, ctx)
do RecordLoader.for(Image).load(product.image_id) end end
HTTP Caching
Solution: Client Side Cache
Normalized Cache
Normalized Cache
query { shop { products { price } } }
query { shop { product(id: 1) { price } } }
{ root: { shop: { products: [ Link.new(1) ] }
}, 1: { price: 1000 } }
https://github.com/facebook/relay http://www.apollostack.com/
Security
Query Depth Timeouts Query Complexity
Future
Subscriptions
subscription { productInventorySubscribe { products { inventory } } }
Deferred Queries
query { shop { name description products { name price
} } }
query { shop { name description products { name price
} } }
query { shop { name description products @defer { name
price } } }
None
None
Thank you Marc-Andre Giroux @__xuorig__