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 with JavaScript
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Radoslav Stankov
November 15, 2015
Programming
350
0
Share
GraphQL with JavaScript
My GraphQL presentation from JSTalks
Radoslav Stankov
November 15, 2015
More Decks by Radoslav Stankov
See All by Radoslav Stankov
Building LLM Powered Features
rstankov
0
130
Tips for Tailwind CSS
rstankov
0
45
Building LLM Powered Features (lightning talk)
rstankov
0
61
All you need is CSS
rstankov
0
140
Ruby on Rails The Single Engineer Framework
rstankov
0
48
Rails: The Missing Parts
rstankov
1
240
The dream that turned into nightmare
rstankov
0
320
The dream that turned into nightmare (lightning)
rstankov
0
120
Ruby on Rails - The Single Engineer Framework
rstankov
0
350
Other Decks in Programming
See All in Programming
一度始めたらやめられない開発効率向上術 / Findy あなたのdotfilesを教えて!
k0kubun
4
2.9k
Swift Concurrency Type System
inamiy
0
410
forteeの改修から振り返るPHPerKaigi 2026
muno92
PRO
3
250
Don't Prompt Harder, Structure Better
kitasuke
0
640
Offline should be the norm: building local-first apps with CRDTs & Kotlin Multiplatform
renaudmathieu
0
170
VueエンジニアがReactを触って感じた_設計の違い
koukimiura
0
160
安いハードウェアでVulkan
fadis
1
940
Feature Toggle は捨てやすく使おう
gennei
0
510
メッセージングを利用して時間的結合を分離しよう #phperkaigi
kajitack
3
570
PDI: Como Alavancar Sua Carreira e Seu Negócio
marcelgsantos
0
110
Coding at the Speed of Thought: The New Era of Symfony Docker
dunglas
0
4.7k
RSAが破られる前に知っておきたい 耐量子計算機暗号(PQC)入門 / Intro to PQC: Preparing for the Post-RSA Era
mackey0225
3
130
Featured
See All Featured
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.3k
Code Reviewing Like a Champion
maltzj
528
40k
How STYLIGHT went responsive
nonsquared
100
6k
sira's awesome portfolio website redesign presentation
elsirapls
0
210
Testing 201, or: Great Expectations
jmmastey
46
8.1k
We Have a Design System, Now What?
morganepeng
55
8.1k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
1
350
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Docker and Python
trallard
47
3.8k
ラッコキーワード サービス紹介資料
rakko
1
3M
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Transcript
Implementing GraphQL with JavaScript Radoslav Stankov 21/10/2015
Radoslav Stankov @rstankov http://rstankov.com http://blog.rstankov.com http://github.com/rstankov
None
None
None
None
None
None
GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post
headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter_id: 1 }
None
None
GET /api/users/1 { id: 1, name: 'User Name', handle: 'user_name',
avatar_url: 'assets.producthunt.com/uuid' }
Rest Client Rest Server
Rest Client Rest Server /api/posts?date=2015-10-31
Rest Client Rest Server /api/posts?date=2015-10-31 /api/users/{x} (for X users)
Rest Client Rest Server /api/posts?date=2015-10-31 /api/users/{x} (for X users)
…approach 2
GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post
headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter: { id: 1, name: 'User Name', handle: 'user_name', avatar_url: 'assets.producthunt.com/uuid' } }
None
None
None
None
None
None
GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post
headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter: { id: 1, name: 'User Name', handle: 'user_name', avatar_url: 'assets.producthunt.com/uuid' }, makers: [{ id: 2, name: 'Second User', handle: 'second_user', avatar_url: 'assets.producthunt.com/uuid' }] }
None
None
None
GET /api/posts?date=2015-10-31 { id: 1, title: "Post title", tagline: "Post
headline", votes_count: 1, comments_count: 1, url: '/category/slug', thumbnail_url: 'assets.producthunt.com/uuid', hunter: { id: 1, name: 'User Name', handle: 'user_name', avatar_url: 'assets.producthunt.com/uuid' }, makers: [{ id: 2, name: 'Second User', handle: 'second_user', avatar_url: 'assets.producthunt.com/uuid' }], platform: [{ name: 'iPhone', }, { name: 'Mac', }, { name: 'Web', }] }
None
None
…approach 3
None
Rest Client Rest Server
Rest Client Rest Server endpoint 1 feature 1
Rest Client Rest Server endpoint 1 feature 1 endpoint 2
feature 2
Rest Client Rest Server endpoint 1 feature 1 endpoint 2
feature 2 endpoint 3 feature 3
Rest Client Rest Server endpoint 1 feature 1 endpoint 2
feature 2 endpoint 3 feature 3 endpoint N feature N
None
None
None
None
None
None
{ id: 1, title: "Post title", tagline: "Post headline", votes_count:
1, hunter: { id: 1, avatar_url: 'assets.producthunt.com/uuid' }, makers: [{ id: 2, avatar_url: 'assets.producthunt.com/uuid' }] }
{ id title tagline votes_count hunter { id avatar_url }
makers { id avatar_url } }
None
GET /graphql Request Body Response Body
query { post(id: 1){ id title tagline votes_count hunter
{ id avatar_url } makers { id avatar_url } } } GET /graphql Request Body Response Body
query { post(id: 1){ id title tagline votes_count hunter
{ id avatar_url } makers { id avatar_url } } } GET /graphql Request Body Response Body
query { post(id: 1){ id title tagline votes_count hunter
{ id avatar_url } makers { id avatar_url } } } GET /graphql Request Body Response Body { "data": { "post": { "id": 1, "title": "title", "tagline": "tagline", "votes_count": 0, "hunter": { "id": 1, "avatar_url": "assets.producthu }, "makers": [ { "id": 1, "avatar_url": "assets.product } ] } } }
It’s that simple
https://facebook.github.io/graphql
GraphQL is a query language created by Facebook in 2012
which provides a common interface between the client and the server for data fetching and manipulations. The client asks for various data from the GraphQL server via queries.
Architecture GraphQL Library (Per-Language) Type Definitions Application
Code
GraphQL • Single endpoint • Not just a library •
Application-Layer Protocol • Server agnostic • Strongly-typed • Client-specified queries • Hierarchical
Tries to solve • N+1 API queries • API response
bloat • Documentation • Ad Hoc Endpoints • Structure issues
Code var RootQueryType = new GraphQLObjectType({ name: 'RootQueryType', fields: {
post: { type: PostType, description: 'Find post by id', args: { id: { description: 'Post id' type: new GraphQLNonNull(GraphQLInt) } }, resolve: function(_, params) { return data.posts.find(params.id); } }, });
Code var PostType = new GraphQLObjectType({ name: 'Post', fields: function()
{ return { id: { type: GraphQLInt, }, title: { type: GraphQLString, }, user: { type: UserType, description: "Creator of the post", resolve: function(post) { return data.users.find(post.user_id); } }, }; } });
Code var [TYPE] = new GraphQLObjectType({ name: [NAME], description: [DESCRIPTION],
fields: function() { return { [FIELD_NAME]: { description: [DESCRIPTION], deprecation: [DEPRECATION MARKER], type: [TYPE], args: [LIST OF FIELD ARGUMENT], resolve: [FUNCTION] }, } } });
Code var PostType = new GraphQLObjectType({ name: 'Post', fields: function()
{ return { id: { type: GraphQLInt, resolve: function(post) { return post.id; } }, user: { type: UserType, resolve: function(post) { return data.users.find(post.user_id); } }, }; } });
Code var PostType = new GraphQLObjectType({ name: 'Post', fields: function()
{ return { id: { type: GraphQLInt }, user: { type: UserType, resolve: function(post) { return data.users.find(post.user_id); } }, }; } });
Query query { post(id: 1){ id title tagline votes_count
hunter { id avatar_url } makers { id avatar_url } } } { "data": { "post": { "id": 1, "title": "title", "tagline": "tagline", "votes_count": 0, "hunter": { "id": 1, "avatar_url": "assets.producthun }, "makers": [ { "id": 1, "avatar_url": "assets.producth } ] } } }
Mutation mutation { createUser(name: "Rado") { id } }
{ "data": { "createSpeaker": { "id": 2 } } }
Code var RootMutationType = new GraphQLObjectType({ name: 'RootMutationType', fields: {
createPost: { type: PostType, args: { title: { type: new GraphQLNonNull(GraphQLString) }, tagline: { type: new GraphQLNonNull(GraphQLString) }, user_id: { type: new GraphQLNonNull(GraphQLInt) }, }, resolve: function(_, params) { if (!data.users.find(params.user_id)) { throw "Invalid user id - " + params.user_id; } return data.posts.create(params); }, }, }, });
Documentation query { __schema { types { name fields
{ name type { name kind ofType { name kind } } } } } } { "data": { "__schema": { "types": [ { "name": "Query", "fields": [ { "name": "user", "type": { "name": "Non-Null", "kind": "NON_NULL", "ofType": { "name": "User", "kind": "OBJECT" } } }, { "name": "post", "type": { "name": "Non-Null", "kind": "NON_NULL", "ofType": { "name": "Post", "kind": "OBJECT" } } } ] },
{ id hunter: { id name small_avatar_url: avatar_url(size: 100) big_avatar_url:
avatar_url(size: 400) } } Cool tricks
Code var UserType = new GraphQLObjectType({ name: 'User', fields: function()
{ return { // ... some field definitions ... picture: { type: GraphQLString, args: { size: { type: GraphQLInt }, }, resolve: function(user, params) { var size = params.size || 400; return 'file.example.com/' + user.picture_uuid + "?size=" + size; } }, }; } });
query withFragments { user(id: 4) { friends(first: 10) { ...friendFields
} mutualFriends(first: 10) { ...friendFields } } } fragment friendFields on User { id name profilePic(size: 50) } Cool tricks
https://facebook.github.io/react
https://facebook.github.io/relay
None
PostContainer = Relay.createContainer(Post, { fragments: { post: () => Relay.QL`
fragment on Post { id title tagline votes_count } `, }, }); Relay
Demo
Issues • New, just a draft specification • Mutations are
weird • Best practices and solutions • Large datasets
None
https://speakerdeck.com/rstankov/introduction-to-graphql
https://github.com/rstankov/talks-code
None
None
@rstankov Thanks :)
Questions?