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
Radoslav Stankov
November 15, 2015
Programming
0
290
GraphQL with JavaScript
My GraphQL presentation from JSTalks
Radoslav Stankov
November 15, 2015
Tweet
Share
More Decks by Radoslav Stankov
See All by Radoslav Stankov
Ruby on Rails The Single Engineer Framework
rstankov
0
3
Rails: The Missing Parts
rstankov
1
130
The dream that turned into nightmare
rstankov
0
230
The dream that turned into nightmare (lightning)
rstankov
0
65
Ruby on Rails - The Single Engineer Framework
rstankov
0
270
Living Without Exceptions
rstankov
1
240
One engineer company with Ruby on Rails
rstankov
2
690
Eliminating noise from your code
rstankov
0
130
Best JavaScript is No Javascript
rstankov
0
160
Other Decks in Programming
See All in Programming
サービスクラスのありがたみを発見したときの思い出 #phpcon_odawara
77web
4
620
趣味全開のAITuber開発
kokushin
0
190
マルチアカウント環境での、そこまでがんばらない RI/SP 運用設計
wa6sn
0
710
Coding Experience Cpp vs Csharp - meetup app osaka@9
harukasao
0
720
PHP で学ぶ OAuth 入門
azuki
1
120
Code smarter, not harder - How AI Coding Tools Boost Your Productivity | Webinar 2025
danielsogl
0
120
SQL Server ベクトル検索
odashinsuke
0
160
Qiita Bash
mercury_dev0517
1
180
データベースエンジニアの仕事を楽にする。PgAssistantの紹介
nnaka2992
9
4.5k
Firebase Dynamic Linksの代替手段を自作する / Create your own Firebase Dynamic Links alternative
kubode
0
230
remix + cloudflare workers (DO) docker上でいい感じに開発する
yoshidatomoaki
0
120
Kubernetesで実現できるPlatform Engineering の現在地
nwiizo
3
1.9k
Featured
See All Featured
Git: the NoSQL Database
bkeepers
PRO
430
65k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
13
660
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
13
1.4k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
30k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.6k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
47
2.4k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
The Cult of Friendly URLs
andyhume
78
6.3k
Code Review Best Practice
trishagee
67
18k
Making Projects Easy
brettharned
116
6.1k
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?