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
320
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
Building LLM Powered Features (lightning talk)
rstankov
0
17
All you need is CSS
rstankov
0
58
Ruby on Rails The Single Engineer Framework
rstankov
0
12
Rails: The Missing Parts
rstankov
1
170
The dream that turned into nightmare
rstankov
0
260
The dream that turned into nightmare (lightning)
rstankov
0
83
Ruby on Rails - The Single Engineer Framework
rstankov
0
310
Living Without Exceptions
rstankov
1
260
One engineer company with Ruby on Rails
rstankov
2
760
Other Decks in Programming
See All in Programming
速いWebフレームワークを作る
yusukebe
5
1.7k
もうちょっといいRubyプロファイラを作りたい (2025)
osyoyu
0
310
JSONataを使ってみよう Step Functionsが楽しくなる実践テクニック #devio2025
dafujii
0
360
為你自己學 Python - 冷知識篇
eddie
1
340
オープンセミナー2025@広島LT技術ブログを続けるには
satoshi256kbyte
0
160
TROCCO×dbtで実現する人にもAIにもやさしいデータ基盤
nealle
0
1.2k
FindyにおけるTakumi活用と脆弱性管理のこれから
rvirus0817
0
420
MCPでVibe Working。そして、結局はContext Eng(略)/ Working with Vibe on MCP And Context Eng
rkaga
5
1.9k
Rancher と Terraform
fufuhu
2
200
CSC305 Summer Lecture 12
javiergs
PRO
0
130
アセットのコンパイルについて
ojun9
0
110
Protocol Buffersの型を超えて拡張性を得る / Beyond Protocol Buffers Types Achieving Extensibility
linyows
0
110
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
840
Fireside Chat
paigeccino
39
3.6k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
910
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.8k
Rails Girls Zürich Keynote
gr2m
95
14k
Side Projects
sachag
455
43k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
187
54k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.5k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
61k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Visualization
eitanlees
148
16k
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?