SlideShare a Scribd company logo
1 of 95
Download to read offline
GraphQL
the holy contract between 

client and server
Pavel Chertorogov
@nodkz
with GraphQL since 2015
Client-server

intro
3
Intro4
Client-server apps
SERVER CLIENTS
NodeJS
C#
.NET Go
Java Python
Ruby etc…
Browsers
iOS
Android
etc…
MySQL
MongoDB
ES
PostgreSQL
Redis
etc…
HTTP
WS
HTML
REST
XML
JSON
etc…
URL
url-encoded
form-data
etc…
Intro5
Invoice Customer
id
name
id
customer_id
amount
1*
date
Simple DB Schema Diagram
Backend capabilities
Intro6
Drupal8 Schema (60 tables) SalesLogix Schema (168 tables)
Wordpress 4.4.2 Schema (12 tables)
Intro7
… and even more Monster with 333 tables
Magento: Commerce Solutions for Selling Online (333 tables)Hi-Res: http://anna.voelkl.at/wp-content/uploads/2016/12/ce2.1.3.png
Order table

(138 fields)
Intro8
How to create API 

for this db-schema 

HELL?
Intro9
Wait! I have a better plan!
GraphQL Basics10
Wikipedia MBT-70 schema
This is GraphQL Schema
GraphQL 

basics
11
GraphQL Basics12
GraphQL – is a …
query 

language

for APIs
query 

executor

on Schema
for Frontenders for Backenders
+
NodeJS
C#
.NET
Go
Python
Ruby
etc…
GraphQL Basics13
GraphQL Query Language
GraphQL query Response in JSON
GraphQL Basics14
GraphQL Query Language
GraphQL query Response in JSON
GraphQL Basics15
GraphQL Schema
Query Mutation Subscription
Type
Single entrypoint
READ (stateless) WRITE (stateless) EVENTS (stateful)
GraphQL Schema
Type Type
GraphQL Basics16
Type
Field 1
Field N
Invoice
id
customerId
amount
Type
Field
Field
Field
date Field
ObjectType
Name
Name
GraphQL Basics17
Function with fetch logic from any data source
Type
Args
Resolve
Scalar or Object Type which returns resolve
Set of input args for resolve function
Description
DeprecationReason
Documentation
Field hiding
Type
Field 1
Field N
Field Config
GraphQL Basics18
Invoice Customer
id
name
id
customerId
amount
1
*
Type Type
Field
Field
Field
Field
Field
date Field
Int
Int
Int
String
Decimal
Date
Relations between types
id
GraphQL Basics19
Invoice Customer1*
One does not simply draw a relation line in GraphQL!
GraphQL Basics20
Invoice Customer
id
name
id
customerId
amount
Type Type
Field
Field
Field
Field
Field
customer
invoices Field
date Field
select * from customer where 

id = {invoice.customerId}
select * from invoice where 

customer_id = {customer.id}
Field Resolve
Resolve
Customer
Array<Invoice>
Relation is a new field in your Type
GraphQL Basics21
Invoice Customer
id
name
id
customerId
amount
Type Type
Field
Field
Field
Field
Field
invoices Field
date Field
select * from invoice where 

customer_id = {customer.id} 

limit {args.limit}
Resolve
Args
Limit: 3
— Limit? Offset? Sort? Additional filtering?
— No problem, add them to args and process in resolve function!
Array<Invoice>
GraphQL Basics22
function
// fetch data logic (from any mix of DBs)
// access logic (check permissions)
ANY PRIVATE BUSINESS LOGIC…
// processing logic (operations, calcs)
source, args, context, info( ) {
}
return data;
Resolve function
GraphQL Basics23
ResolveJust remove
and you get PUBLIC schema
functions
printSchema(schema); // txt output (SDL format)



graphql(schema, introspectionQuery); // json output (AST)
(private business logic)
Schema Introspection
GraphQL Basics24
• types
• fields
• args
• docs
• resolve
• directives
• input types
• enums
• interfaces
• unions
type Customer { 

id: Int 

name: String 

# List of Invoices for current Customer 

invoices(limit: Int): [Invoice] 

} 



# Show me the money

type Invoice { 

id: Int 

customerId: Int 

amount: Decimal

# Customer data for current Invoice 

customer: Customer 

oldField: Int @deprecated(reason: "will be removed") 

}
SDL format
(txt)
Schema Introspection example
GraphQL Basics25
an ability for awesome tooling:
GraphiQL — graphical interactive in-browser GraphQL IDE
Eslint-plugin-graphql — check queries in your editor, CI
Relay-compiler — generates type definitions from queries
• Autocompletion
• Query validation
• Documentation
• Visualization
• TypeDefs generation for static analysis (Flow, TypeScript)
Schema Introspection provides
GraphQL Basics26
const QueryType = new GraphQLObjectType({ 

name: 'Query', 

fields: () => ({ 

films: { 

type: new GraphQLList(FilmType), 

args: { 

limit: { type: GraphQLInt, defaultValue: 5 }, 

}, 

resolve: async (source, args) => { 

const data = await loadData(`https://swapi.co/api/films/`); 

return data.slice(0, args.limit); 

}, 

}, 

...otherFields, 

}), 

});
Type definition example
GraphQL Basics27
const QueryType = new GraphQLObjectType({ 

name: 'Query', 

fields: () => ({ 

films: { 

type: new GraphQLList(FilmType), 

args: { 

limit: { type: GraphQLInt, defaultValue: 5 }, 

}, 

resolve: async (source, args) => { 

const data = await loadData(`...`); 

return data.slice(0, args.limit); 

}, 

}, 

...otherFields, 

}), 

});
Query
Type
type
args
resolve
field
FieldConfig
Type
Args
Resolve
Description
DeprecationReason
Type
Field 1
Field N
Type definition example
GraphQL Basics28
• input types
• directives
• enums
• interfaces
• unions
• fragments
Don’t forget to read about
http://graphql.org/learn/
Client requirements
https://graphql-compose.herokuapp.com/
Backend capabilities
GraphQL
Demo
29
30
REST API
GraphQL
Fetch sub-fetch 1
sub-fetch 2
sub-fetch N
Network
Delay
Network
Delay
RESULT
Query Network
Delay
RESULT
- Sub-fetch logic on client side (increase bundle size)
+ Sub-fetch logic implemented on server side
+ No additional network round-trip (speed)
- Over-fetching (redundant data transfer/parsing)
+ Exactly requested fields (speed)
Intro31
A copy from one of the previous slides…
Client-server apps
SERVER CLIENTS
NodeJS
C#
.NET Go
Java Python
Ruby etc…
Browsers
iOS
Android
etc…
MySQL
MongoDB
ES
PostgreSQL
Redis
etc…
HTTP
WS
HTML
REST
XML
JSON
etc…
URL
url-encoded
form-data
etc…
32
GraphQL – is a query language for APIs
NodeJS
C#
.NET Go
Java
PythonRuby etc…
Browsers iOS
Androidetc…
MySQL
MongoDB
ES
PostgreSQL
Redis
etc…
HTTP
WS
etc…
SERVER
CLIENTS
Specification for describing 

the capabilities and requirements 

of data models 

for client‐server apps
SCHEMA

INTROSPECTION
Pretty QUERY

Language
Static
Analysis
For frontend

developers
33
Static Analysis34
PRODUCTIVITY
• Holy refactoring
Static type checks 🚀
• Functions call checks
• Types checks
• Auto-suggestion
Static program analysis is the analysis of computer software that is performed without actually executing programs
Static Analysis35
Let’s turbo-charge 

our client apps static analysis

with GraphQL queries
SERVER JS CLIENT
File with

GraphQL Query

and Response processing
GraphQL
Schema
Static Analysis36
SERVER JS CLIENT
File with

GraphQL Query

and Response processing
Schema
Introspection
GraphQL
Schema
1
Static Analysis37
Relay-compiler
Apollo-codegen
SERVER JS CLIENT
File with

GraphQL Query

and Response processing
Schema
Introspection
GraphQL
Schema
Watcher
1
2
Static Analysis38
Hey, you have a wrong Query
SERVER JS CLIENT
File with

GraphQL Query

and Response processing
Schema
Introspection
GraphQL
Schema
Watcher
File with 

Response Type Defs
1
2 3
Static Analysis39
SERVER JS CLIENT
File with

GraphQL Query

and Response processing
Schema
Introspection
GraphQL
Schema
Watcher
File with 

Response Type Defs
1
2 3
4
Static Analysis
SERVER JS CLIENT
File with

GraphQL Query

and Response processing
Schema
Introspection
GraphQL
Schema
Watcher Flowtype
File with 

Response Type Defs
1
2 3
4
5
40
or TypeScript
Static Analysis41
SERVER JS CLIENT
File with

GraphQL Query

and Response processing
Schema
Introspection
GraphQL
Schema
Watcher Flowtype
File with 

Response Type Defs
1
2 3
4
5
Houston, we have a Type Check problem
at line 19287 col 5: possible undefined value
6
Static Analysis42
GraphQL Query
Generated Response Type Def
Flow error
Crappy Code
DEMO
Flow typed Code
Static Analysis
import { graphql } from 'react-relay'; 

const query = graphql` 

query BalanceQuery { 

viewer { 

cabinet { 

accountBalance 

} 

} 

}`;
43
GraphQL Query
Balance.js
JS CLIENT
File with

GraphQL Query

and Response processing
Watcher Flowtype
File with 

Response Type Defs
3
4
5
Static Analysis
/* @flow */ 

/*:: 

export type BalanceQueryResponse = {| 

+viewer: ?{| 

+cabinet: ?{| 

+accountBalance: ?number; 

|}; 

|}; 

|}; 

*/
44
Generated Response Type Def
Writer time: 0.53s [0.37s compiling, …]
Created:
- BalanceQuery.graphql.js
Unchanged: 291 files
Written default in 0.61s
__generated__/BalanceQuery.graphql.js
JS CLIENT
File with

GraphQL Query

and Response processing
Watcher Flowtype
File with 

Response Type Defs
3
4
5
Static Analysis45
Crappy Codeimport { graphql } from 'react-relay'; 

import * as React from 'react'; 



export default class Balance extends React.Component { 

render() { 

const { viewer } = this.props; 

return <div>
Balance {viewer.cabinet.accountBalance}
</div>; 

} 

} 

const query = graphql`query BalanceQuery { 

viewer { cabinet { accountBalance } }
}`;
Balance.js
JS CLIENT
File with

GraphQL Query

and Response processing
Watcher Flowtype
File with 

Response Type Defs
3
4
5
Static Analysis46
Flow typed Code

import { graphql } from 'react-relay'; 

import * as React from 'react'; 

import type { BalanceQueryResponse } from './__generated__/BalanceQuery.graphql'; 



type Props = BalanceQueryResponse;


export default class Balance extends React.Component<Props> { 

render() { 

const { viewer } = this.props; 

return <div>Balance {viewer.cabinet.accountBalance}</div>; 

} 

} 

const query = graphql`query BalanceQuery { 

viewer { cabinet { accountBalance } } 

}`; 



Balance.js
JS CLIENT
File with

GraphQL Query

and Response processing
Watcher Flowtype
File with 

Response Type Defs
3
4
5
Static Analysis47
Flow typed Code/* @flow */ 

import { graphql } from 'react-relay'; 

import * as React from 'react'; 

import type { BalanceQueryResponse } from './__generated__/BalanceQuery.graphql'; 



type Props = BalanceQueryResponse;


export default class Balance extends React.Component<Props> { 

render() { 

const { viewer } = this.props; 

return <div>Balance {viewer.cabinet.accountBalance}</div>; 

} 

} 

const query = graphql`query BalanceQuery { 

viewer { cabinet { accountBalance } } 

}`; 



Balance.js
JS CLIENT
File with

GraphQL Query

and Response processing
Watcher Flowtype
File with 

Response Type Defs
3
4
5
Static Analysis48
Error: src/_demo/Balance.js:11
11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>;
^^^^^^^ property `cabinet`.
Property cannot be accessed on possibly null value
11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>;
^^^^^^ null
Error: src/_demo/Balance.js:11
11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>;
^^^^^^^ property `cabinet`.
Property cannot be accessed on possibly undefined value
11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>;
^^^^^^ undefined
Flow errors
Static Analysis49
type Props = BalanceQueryResponse;
class Balance extends React.Component<Props> { 

render() { 

const { viewer } = this.props; 

return <div>{viewer.invoices}</div>; 

} 

}
Flow errors for missing field
Static Analysis50
Error: src/_demo/Balance.js:11
11: return <div>{viewer.invoices}</div>;
^^^^^^^^ property `invoices`.
Property not found in
v-
13: +viewer: ?{|
14: +cabinet: ?{|
15: +accountBalance: ?number;
16: |};
17: |};
-^ object type. See: src/_demo/__generated__/
BalanceQuery.graphql.js:13
Flow errors for missing field
51
GraphQL
Query
Problems
For backend

developers
GraphQL Query Problems52
Denial of Service attacks
• pre-approve queries that
the server can execute
(persisted queries by unique ID)
query HugeResponse { 

user { 

friends(limit: 1000) { 

friends(limit: 1000) { 

friends(limit: 1000) { 

... 

} 

} 

} 

} 

}
aka Resource exhaustion attaks
• cost analysis on the query
using by Facebook
Solutions:
• avoid nesting relations
GraphQL Query Problems53
query NestedQueryN1 { 

{ 

productList { 

id 

categoryId 

category { 

id 

name 

} 

} 

} 

}
N+1 query problem
1 query for 

ProductList
N queries 

for fetching every 

Category by id
Solution: DataLoader
const CatLoader = new DataLoader(
ids => Category.findByIds(ids)
);


CatLoader.load(1); 

CatLoader.load(2); 

CatLoader.load(1); 

CatLoader.load(4);
will do just one BATCH request 

on next tick to the Database
Schema
construction 

problems
For backend

developers
54
Problem #1: too much copy/paste55
const QueryType = new GraphQLObjectType({ 

name: 'Query', 

fields: () => ({ 

films: ..., 

persons: ..., 

planets: ..., 

species: ..., 

starships: ..., 

vehicles: ..., 

}), 

});
6 fields and
every FieldConfig

consists from 

almost identical

12 ctrl+c/ctrl+v lines
Query Type example
https://swapi.co
The Star Wars API
Problem #1: too much copy/paste56
films: { 

type: new GraphQLList(FilmType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: async (source, args) => { 

const data = await loadData(`https://swapi.co/api/films/`); 

if (args && args.limit > 0) { 

return data.slice(0, args.limit); 

} 

return data; 

},
FieldConfig example for films field
Problem #1: too much copy/paste
{ 

films: { 

type: new GraphQLList(FilmType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: async (source, args) => { 

const data = await loadData(`https://swapi.co/api/films/`); 

if (args && args.limit > 0) { 

return data.slice(0, args.limit); 

} 

return data; 

}, 

},


planets: { 

type: new GraphQLList(PlanetType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: async (source, args) => { 

const data = await loadData(`https://swapi.co/api/planets/`); 

if (args && args.limit > 0) { 

return data.slice(0, args.limit); 

} 

return data; 

}, 

}, 

} 

57
differs 

only by url
Comparison of two FieldConfigs
Problem #1: too much copy/paste58
function createListResolve(url) { 

return async (source, args) => { 

const data = await loadData(url); 

if (args && args.limit > 0) { 

return data.slice(0, args.limit); 

} 

return data; 

}; 

}
Solution 1: you may generate your resolve functions
create a function 

which returns a resolve function
Problem #1: too much copy/paste


films: { 

type: new GraphQLList(FilmType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: createListResolve(`https://swapi.co/api/films/`), 

}, 



planets: { 

type: new GraphQLList(PlanetType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: createListResolve(`https://swapi.co/api/planets/`), 

}, 

{ 

films: { 

type: new GraphQLList(FilmType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: async (source, args) => { 

const data = await loadData(`https://swapi.co/api/films/`); 

if (args && args.limit > 0) { 

return data.slice(0, args.limit); 

} 

return data; 

}, 

},


planets: { 

type: new GraphQLList(PlanetType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: async (source, args) => { 

const data = await loadData(`https://swapi.co/api/planets/`); 

if (args && args.limit > 0) { 

return data.slice(0, args.limit); 

} 

return data; 

}, 

}, 

} 

59
Solution 1: you may generate your resolve functions
reduce N times 7 LoC to 1 LoC
Problem #1: too much copy/paste


films: { 

type: new GraphQLList(FilmType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: createListResolve(`https://swapi.co/api/films/`), 

}, 



planets: { 

type: new GraphQLList(PlanetType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: createListResolve(`https://swapi.co/api/planets/`), 

}, 

60
Solution 2: you may generate your FieldConfigs
differs only by `Type` and `url`
Problem #1: too much copy/paste61
function createFieldConfigForList(type, url) { 

return { 

type: new GraphQLList(type), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: createListResolve(url), 

}; 

}
Solution 2: you may generate your FieldConfigs
create a function 

which returns a FieldConfig
Problem #1: too much copy/paste62
films: { 

type: new GraphQLList(PlanetType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: createListResolve(`https://swapi.co/api/films/`), 

}, 

planets: { 

type: new GraphQLList(FilmType), 

args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 

resolve: createListResolve(`https://swapi.co/api/planets/`), 

},
{ 

films: createFieldConfigForList(FilmType, `https://swapi.co/api/films/`), 

planets: createFieldConfigForList(PlanetType, `https://swapi.co/api/planets/`), 

}
10 LoC reduced to 2 LoC
Solution 2: you may generate your FieldConfigs
Problem #1: too much copy/paste63
DRY principle

(don't repeat yourself)
was

reduced 

in 3 times
90 LoC
30 LoC
Solution 1: you may generate your resolve functions
Solution 2: you may generate your FieldConfigs
Problem #2: keep GraphQL types in sync with ORM/DB64
With time you may:
• add new fields
• change field types
• remove fields
• rename fields
Model: User Type: User
SYNC
How to keep to Schemas in SYNC?
Problem #2: keep GraphQL types in sync with ORM/DB65
GENERATE
• via some cli/script
• on server boot load (better)
Solution: generate GraphQL types from ORM models
SSOT principle

(single source of truth)
Model: User Type: User
Problem #3: mess in types and resolve functions66
InvoiceType.js CustomerType.js
id
name
id
customerId
amount
customer
invoices
date
select * from CUSTOMER 

where …
select * from INVOICE 

where …
Resolve
Resolve
InvoiceType.js contains CUSTOMER query
CustomerType.js contains INVOICE query
Problem #3: mess in types and resolve functions67
select * from INVOICES where …
CustomerType.js
id
name
invoices
transactions
tickets
events
likes
messages
…
select * from TRANSACTIONS where …
select * from TICKETS where …
select * from EVENTS where …
select * from LIKES where …
select * from MESSAGES where …
select * from …
CustomerType.js knows too much 

about queries of others types
Problem #3: mess in types and resolve functions68
AdminNoteType.js
id
msg
Customer
Product
Invoice
…
Resolve
Resolve
Resolve
Resolve
What if you need to restrict access for some group of users?
Modify resolvers in all places?
Problem #3: mess in types and resolve functions69
Solution: GraphQL Models*
* “GraphQL Model” is not a part of GraphQL specification.



It’s suggested additional layer of abstraction for more
comfortable way to construct and maintain your schema
and relations into it.
Problem #3: mess in types and resolve functions


class CustomerGQLModel { 

type: CustomerGraphQLType; 

resolvers: { 

findById: { 

type: CustomerGraphQLType, 

args: { id: 'Int!' }, 

resolve: (_, args) => 

load(`select * from customer where id = ${args.id}`), 

}, 

findMany: { ... }, 

createOne: { ... }, 

updateOne: { ... }, 

removeOne: { ... }, 

... 

}; 

inputType: CustomerGraphQLInputType;

} 



70
1. type definition
Contains:
2. all possible
ways to CRUD
data
3. may have other
helper methods
and data
Type
MAP<FieldConfig>
InputType
1
2
3
Solution: GraphQL Models
Problem #4: import { makeExecutableSchema } from ‘graphql-tools';
Writing Types via SDL and providing resolvers separately.
71
const schema = makeExecutableSchema({ typeDefs, resolvers }); 

const typeDefs = ` 

type Query { 

customer(id: Int!): Customer
invoices(limit: Int): [Invoice] 

}


type Customer { 

id: Int! 

firstName: String 

invoices: [Invoice] 

}`;
It’s nice developer experience for small to medium sized schema BUT…
const resolvers = { 

Query: { 

customer: (_, { id }) =>
Customer.find({ id: id }),
invoices: (_, { limit }) =>
Invoice.findMany({ limit }),

}, 

Customer: { 

invoices: (source) =>
Invoice.find({ customerId: source.id }), 

}, 

};
type args resolve
Problem #4: import { makeExecutableSchema } from ‘graphql-tools';72
• If one InputType used in several resolvers, then the
complexity of refactoring increases dramatically.
Hard to work with complex input args
type Query {
invoices(filter: FilterInput): [Invoice] 

}


input FilterInput { 

num: Int 

dateRange: DateRangeInput

status: InvoiceStatusEnum

}
input DateRangeInput {
min: Date
max: Date
}
enum InvoiceStatusEnum {

unpaid paid declined

}


invoices: (_, { filter }) => { 

const { num, dateRange, status } = filter; 

const q = {}; 

if (num) q.num = num; 

if (dateRange)
q['date.$inRange'] = dateRange; 

if (status) q.status = status; 

return Post.findMany(q); 

}, 

• If one InputType per resolver, then too much 

copy/paste almost similar types.
All highlighted parts with red lines should be in sync
* This example contains an error in the code, try to find it ;)
Problem #4: import { makeExecutableSchema } from ‘graphql-tools';
Solution: build the schema programmatically
Generate FieldConfigs via your custom functions (Resolvers) …
73
class InvoiceGQLModel { 

findManyResolver(configOptions) { 

return { 

type: InvoiceType, 

args: { 

filter: { type: new GraphQLInputObjectType({ … })}, 

}, 

resolve: (_, args) => Invoice.findMany(args), 

}
}
findByIdResolver() { … }
… … and then …
type
args
resolve
Problem #4: import { makeExecutableSchema } from ‘graphql-tools';74
import { GraphQLSchema, GraphQLObjectType } from 'graphql'; 

import InvoiceResolvers from './InvoiceResolvers'; 



const schema = new GraphQLSchema({ 

query: new GraphQLObjectType({ 

name: 'Query', 

fields: { 

invoices: InvoiceResolvers.findManyResolver(), 

... 

}, 

}), 

});
http://graphql.org/graphql-js/constructing-types/
Solution: build the schema programmatically
…and then build your Schema from fields and your Resolvers
Problem #4: import { makeExecutableSchema } from ‘graphql-tools';75
type Query {
invoices(filter: FilterInput): [Invoice] 

}


invoices: (_, { filter }) => { … }

{ 

type: new GraphQLList(Invoice), 

args: { 

filter: { type: new GraphQLInputObjectType({ … })}, 

}, 

resolve: (_, { filter }) => { … }, 

}
combine code from different places

back to FieldConfig
type args resolve
type
args
resolve
Problem #4: import { makeExecutableSchema } from ‘graphql-tools';76
type Query {
invoices(filter: FilterInput): [Invoice] 

}


invoices: (_, { filter }) => { … }

{ 

type: [Invoice], 

args: { 

filter: `input FilterInput { … }`, 

}, 

resolve: (_, { filter }) => { … }, 

}
my code with

graphql-compose
combine code from different places

back to FieldConfig
Graphql-compose
packages
77
For backend

developers
graphql-compose packages78
Graphql-compose-*
The main idea is to generate GraphQL Schema
from your ORM/Mappings at the server startup
with a small lines of code as possible.
— OSS packages family 

for generating GraphQL Types
MIT License
Exposes Flowtype/Typescript declarations
With awful docs all packages have more than 460 starts on GitHub
Help wanted
graphql-compose packages
Graphql-compose
79
It bundles your Schema
webpackworks almost like a
from different type sources
graphql-compose packages80
ORM Schema,
Mapping
TypeComposer

with Resolvers
GraphQL Schema
Generate editable GraphQL Types

with a set of CRUD Resolvers (FieldConfigs w/ args, type, resolve)
Remove/add fields

Wrap default Resolvers with custom business logic

Create own Resolvers (FieldConfigs)

Build relations between types
Manually created TypeComposers

or Vanilla GraphQL types
1
2
3
Schema creation workflow
graphql-compose packages81
const InvoiceItemTC = TypeComposer.create(` 

type InvoiceItem { 

description: String 

qty: Int 

price: Float 

} 

`); SDL syntax for simple types
(schema definition language)
Graphql-compose provides handy syntax for manual
type creation
graphql-compose packages82
const InvoiceTC = TypeComposer.create({ 

name: 'Invoice', 

fields: { 

id: 'Int!', 

now: { 

type: 'Date', 

resolve: () => Date.now() 

},
items: () => [InvoiceItemTC], 

}, 

});
SDL syntax inside
Type as function, [ ] as List
Config Object Syntax
for complex types
Graphql-compose provides handy syntax for manual
type creation
graphql-compose packages83
TC.hasField('lon'); // boolean 

TC.getFieldNames(); // ['lon', 'lat'] 

TC.getField('lon'); // FieldConfig 

TC.getField('lon'); // return FieldConfig 

TC.getFields(); // { lon: FieldConfig, lat: FieldConfig }
TC.setFields({ ... }); // completely replace all fields 

TC.setField('lon', { ... }); // replace `lon` field with new FieldConfig 

TC.removeField('lon');
TC.removeOtherFields(['lon', 'lat']); // will remove all other fields 

TC.reorderFields(['lat', 'lon']); // reorder fields, lat becomes first 

TC.deprecateFields({ 'lat': 'deprecation reason' }); // mark field as deprecated
TC.getFieldType('lat'); // GraphQLFloat 

TC.getFieldTC('complexField'); // TypeComposer 

TC.getFieldArgs('lat'); // returns map of args config or empty {} if no args 

TC.hasFieldArg('lat', 'arg1'); // false 

TC.getFieldArg('lat', 'arg1'); // returns arg config
TC.addFields({ field1: …, field2: … }); 

TC.removeField(['field2', ‘field3']);
TC.extendField('lat', { description: 'Latitude', resolve: () => {} });
TOP 3 commonly 

used methods
Bunch of other 

useful methods
Graphql-compose provides methods 

for modifying Types
graphql-compose packages84
InvoiceTC.addField('items', { 

type: () => ItemsTC, 

resolve: (source) => { 

return Items.find({ invoiceId: source.id }) 

}, 

});
Graphql-compose create relations between Types
via FieldConfig
Type as function

solves hoisting problems
graphql-compose packages85
InvoiceTC.addRelation('items', { 

resolver: () => ItemsTC.getResolver('findMany'), 

prepareArgs: { 

filter: source => ({ invoiceId: source.id }), 

}, 

});
Graphql-compose create relations between Types
via Resolvers
Prepare args for Resolver
graphql-compose packages86
graphql-compose-mongoose
graphql-compose-json
graphql-compose-elasticsearch
graphql-compose-pagination
graphql-compose-connection
graphql-compose-relay
type generator
resolver generator
type/resolver modifier
Graphql-compose is a great tool for writing your
own type generators/plugins
type generator
resolver generator
resolver generator
type generator resolver generator
http API wrapper
graphql-compose-aws SDK API wrapper🌶
graphql-compose packages87
graphql-compose-aws
~700 lines of code, 2 days of work
generates more than 10 000 GraphQL Types
schema size ~2 Mb in SDL, ~9 Mb in json
Huge GraphQL Schema example
JUST IN 2 DAYS
graphql-compose packages88
125 Services 3857 Operations 6711 Input/Output params
https://graphqlbin.com/plqhO
AWS Cloud API in GraphQL Schema generation takes about ~1-2 seconds
graphql-compose packages89
https://github.com/nodkz/graphql-compose-examples
https://github.com/lyskos97/graphql-compose-swapi
Mongoose, Elastic, Northwind
Wrapping REST API
Graphql-compose schema demos
https://graphql-compose.herokuapp.com
https://graphql-compose-swapi.herokuapp.com
90
Last words…
91
GraphQL
less network traffic
less time on coding
less errors
less stress more success
is awesome!
👍
PS. SOMETIMES A LOT LESS
Tutorials92
howtographql.com
medium graphql
youtube graphql
Read
Watch
Glue
93
Take away!
GraphQL is powerful query language 

with great tools
GraphQL is typed so it helps with 

static analysis on clients
Generate GraphQL Schemas on server
94
Pavel Chertorogov
THANKS!
nodkz
95
GraphQL
is a
server and client apps
for your

More Related Content

What's hot

How web works and browser works ? (behind the scenes)
How web works and browser works ? (behind the scenes)How web works and browser works ? (behind the scenes)
How web works and browser works ? (behind the scenes)Vibhor Grover
 
NGRX Apps in Depth
NGRX Apps in DepthNGRX Apps in Depth
NGRX Apps in DepthTrayan Iliev
 
An intro to GraphQL
An intro to GraphQLAn intro to GraphQL
An intro to GraphQLvaluebound
 
Writing code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongVu Huy
 
How to build an ETL pipeline with Apache Beam on Google Cloud Dataflow
How to build an ETL pipeline with Apache Beam on Google Cloud DataflowHow to build an ETL pipeline with Apache Beam on Google Cloud Dataflow
How to build an ETL pipeline with Apache Beam on Google Cloud DataflowLucas Arruda
 
SVR17: Data-Intensive Computing on Windows HPC Server with the ...
SVR17: Data-Intensive Computing on Windows HPC Server with the ...SVR17: Data-Intensive Computing on Windows HPC Server with the ...
SVR17: Data-Intensive Computing on Windows HPC Server with the ...butest
 
GraphQL Introduction
GraphQL IntroductionGraphQL Introduction
GraphQL IntroductionSerge Huber
 
Graphql presentation
Graphql presentationGraphql presentation
Graphql presentationVibhor Grover
 
Introduction to GraphQL at API days
Introduction to GraphQL at API daysIntroduction to GraphQL at API days
Introduction to GraphQL at API daysyann_s
 
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/Meteor
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/MeteorWhy UI Developers Love GraphQL - Sashko Stubailo, Apollo/Meteor
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/MeteorJon Wong
 
GraphQL, Redux, and React
GraphQL, Redux, and ReactGraphQL, Redux, and React
GraphQL, Redux, and ReactKeon Kim
 
Применение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисовПрименение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисовCOMAQA.BY
 
GraphQL in an Age of REST
GraphQL in an Age of RESTGraphQL in an Age of REST
GraphQL in an Age of RESTYos Riady
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India
 
Introduction to Datasource V2 API
Introduction to Datasource V2 APIIntroduction to Datasource V2 API
Introduction to Datasource V2 APIdatamantra
 
Making Machine Learning Easy with H2O and WebFlux
Making Machine Learning Easy with H2O and WebFluxMaking Machine Learning Easy with H2O and WebFlux
Making Machine Learning Easy with H2O and WebFluxTrayan Iliev
 
Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...
Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...
Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...NLJUG
 
Building GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & PrismaBuilding GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & PrismaNikolas Burk
 

What's hot (20)

How web works and browser works ? (behind the scenes)
How web works and browser works ? (behind the scenes)How web works and browser works ? (behind the scenes)
How web works and browser works ? (behind the scenes)
 
NGRX Apps in Depth
NGRX Apps in DepthNGRX Apps in Depth
NGRX Apps in Depth
 
An intro to GraphQL
An intro to GraphQLAn intro to GraphQL
An intro to GraphQL
 
Writing code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen Luong
 
How to build an ETL pipeline with Apache Beam on Google Cloud Dataflow
How to build an ETL pipeline with Apache Beam on Google Cloud DataflowHow to build an ETL pipeline with Apache Beam on Google Cloud Dataflow
How to build an ETL pipeline with Apache Beam on Google Cloud Dataflow
 
SVR17: Data-Intensive Computing on Windows HPC Server with the ...
SVR17: Data-Intensive Computing on Windows HPC Server with the ...SVR17: Data-Intensive Computing on Windows HPC Server with the ...
SVR17: Data-Intensive Computing on Windows HPC Server with the ...
 
Intro to GraphQL
 Intro to GraphQL Intro to GraphQL
Intro to GraphQL
 
B_110500002
B_110500002B_110500002
B_110500002
 
GraphQL Introduction
GraphQL IntroductionGraphQL Introduction
GraphQL Introduction
 
Graphql presentation
Graphql presentationGraphql presentation
Graphql presentation
 
Introduction to GraphQL at API days
Introduction to GraphQL at API daysIntroduction to GraphQL at API days
Introduction to GraphQL at API days
 
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/Meteor
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/MeteorWhy UI Developers Love GraphQL - Sashko Stubailo, Apollo/Meteor
Why UI Developers Love GraphQL - Sashko Stubailo, Apollo/Meteor
 
GraphQL, Redux, and React
GraphQL, Redux, and ReactGraphQL, Redux, and React
GraphQL, Redux, and React
 
Применение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисовПрименение паттерна Page Object для автоматизации веб сервисов
Применение паттерна Page Object для автоматизации веб сервисов
 
GraphQL in an Age of REST
GraphQL in an Age of RESTGraphQL in an Age of REST
GraphQL in an Age of REST
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 Overview
 
Introduction to Datasource V2 API
Introduction to Datasource V2 APIIntroduction to Datasource V2 API
Introduction to Datasource V2 API
 
Making Machine Learning Easy with H2O and WebFlux
Making Machine Learning Easy with H2O and WebFluxMaking Machine Learning Easy with H2O and WebFlux
Making Machine Learning Easy with H2O and WebFlux
 
Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...
Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...
Modularity and Domain Driven Design; a killer Combination? - Tom de Wolf & St...
 
Building GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & PrismaBuilding GraphQL Servers with Node.JS & Prisma
Building GraphQL Servers with Node.JS & Prisma
 

Similar to GraphQL the holy contract between client and server

Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) ExtensionSimplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) ExtensionVMware Tanzu
 
GraphQL_devoxx_2023.pptx
GraphQL_devoxx_2023.pptxGraphQL_devoxx_2023.pptx
GraphQL_devoxx_2023.pptxSoham Dasgupta
 
Domain Driven Design Tactical Patterns
Domain Driven Design Tactical PatternsDomain Driven Design Tactical Patterns
Domain Driven Design Tactical PatternsRobert Alexe
 
APIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBM
APIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBMAPIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBM
APIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBMapidays
 
VBA API for scriptDB primer
VBA API for scriptDB primerVBA API for scriptDB primer
VBA API for scriptDB primerBruce McPherson
 
GraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database accessGraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database accessConnected Data World
 
Code-first GraphQL Server Development with Prisma
Code-first  GraphQL Server Development with PrismaCode-first  GraphQL Server Development with Prisma
Code-first GraphQL Server Development with PrismaNikolas Burk
 
GraphQL-ify your API - JFall 2022
GraphQL-ify your API - JFall 2022GraphQL-ify your API - JFall 2022
GraphQL-ify your API - JFall 2022Soham Dasgupta
 
Building a GraphQL API in PHP
Building a GraphQL API in PHPBuilding a GraphQL API in PHP
Building a GraphQL API in PHPAndrew Rota
 
Implementing OpenAPI and GraphQL services with gRPC
Implementing OpenAPI and GraphQL services with gRPCImplementing OpenAPI and GraphQL services with gRPC
Implementing OpenAPI and GraphQL services with gRPCTim Burks
 
GraphQL - an elegant weapon... for more civilized age
GraphQL - an elegant weapon... for more civilized ageGraphQL - an elegant weapon... for more civilized age
GraphQL - an elegant weapon... for more civilized ageBartosz Sypytkowski
 
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and TypescriptMongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and TypescriptMongoDB
 
Your API on Steroids - Retrofitting GraphQL by Code, Cloud Native or Serverless
Your API on Steroids - Retrofitting GraphQL by Code, Cloud Native or ServerlessYour API on Steroids - Retrofitting GraphQL by Code, Cloud Native or Serverless
Your API on Steroids - Retrofitting GraphQL by Code, Cloud Native or ServerlessQAware GmbH
 
GraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedGraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedMarcinStachniuk
 
SETCON'18 - Ilya labacheuski - GraphQL adventures
SETCON'18 - Ilya labacheuski - GraphQL adventuresSETCON'18 - Ilya labacheuski - GraphQL adventures
SETCON'18 - Ilya labacheuski - GraphQL adventuresNadzeya Pus
 
Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.Keshav Murthy
 
Getting started with Apollo Client and GraphQL
Getting started with Apollo Client and GraphQLGetting started with Apollo Client and GraphQL
Getting started with Apollo Client and GraphQLMorgan Dedmon
 

Similar to GraphQL the holy contract between client and server (20)

Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) ExtensionSimplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
Simplify Access to Data from Pivotal GemFire Using the GraphQL (G2QL) Extension
 
GraphQL_devoxx_2023.pptx
GraphQL_devoxx_2023.pptxGraphQL_devoxx_2023.pptx
GraphQL_devoxx_2023.pptx
 
Domain Driven Design Tactical Patterns
Domain Driven Design Tactical PatternsDomain Driven Design Tactical Patterns
Domain Driven Design Tactical Patterns
 
APIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBM
APIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBMAPIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBM
APIdays Helsinki 2019 - GraphQL API Management with Amit P. Acharya, IBM
 
VBA API for scriptDB primer
VBA API for scriptDB primerVBA API for scriptDB primer
VBA API for scriptDB primer
 
GraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database accessGraphQL and its schema as a universal layer for database access
GraphQL and its schema as a universal layer for database access
 
Graphql usage
Graphql usageGraphql usage
Graphql usage
 
Code-first GraphQL Server Development with Prisma
Code-first  GraphQL Server Development with PrismaCode-first  GraphQL Server Development with Prisma
Code-first GraphQL Server Development with Prisma
 
GraphQL-ify your API - JFall 2022
GraphQL-ify your API - JFall 2022GraphQL-ify your API - JFall 2022
GraphQL-ify your API - JFall 2022
 
Building a GraphQL API in PHP
Building a GraphQL API in PHPBuilding a GraphQL API in PHP
Building a GraphQL API in PHP
 
Implementing OpenAPI and GraphQL services with gRPC
Implementing OpenAPI and GraphQL services with gRPCImplementing OpenAPI and GraphQL services with gRPC
Implementing OpenAPI and GraphQL services with gRPC
 
GraphQL - an elegant weapon... for more civilized age
GraphQL - an elegant weapon... for more civilized ageGraphQL - an elegant weapon... for more civilized age
GraphQL - an elegant weapon... for more civilized age
 
React inter3
React inter3React inter3
React inter3
 
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and TypescriptMongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
MongoDB.local Berlin: Building a GraphQL API with MongoDB, Prisma and Typescript
 
Your API on Steroids - Retrofitting GraphQL by Code, Cloud Native or Serverless
Your API on Steroids - Retrofitting GraphQL by Code, Cloud Native or ServerlessYour API on Steroids - Retrofitting GraphQL by Code, Cloud Native or Serverless
Your API on Steroids - Retrofitting GraphQL by Code, Cloud Native or Serverless
 
GraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learnedGraphQL - when REST API is not enough - lessons learned
GraphQL - when REST API is not enough - lessons learned
 
SETCON'18 - Ilya labacheuski - GraphQL adventures
SETCON'18 - Ilya labacheuski - GraphQL adventuresSETCON'18 - Ilya labacheuski - GraphQL adventures
SETCON'18 - Ilya labacheuski - GraphQL adventures
 
Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.Distributed Queries in IDS: New features.
Distributed Queries in IDS: New features.
 
Getting started with Apollo Client and GraphQL
Getting started with Apollo Client and GraphQLGetting started with Apollo Client and GraphQL
Getting started with Apollo Client and GraphQL
 
Grails 101
Grails 101Grails 101
Grails 101
 

Recently uploaded

Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Dr.Costas Sachpazis
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls in Nagpur High Profile
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxAsutosh Ranjan
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSSIVASHANKAR N
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingrknatarajan
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxupamatechverse
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlysanyuktamishra911
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesPrabhanshu Chaturvedi
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...Call Girls in Nagpur High Profile
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...ranjana rawat
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Bookingdharasingh5698
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxupamatechverse
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 

Recently uploaded (20)

Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
Coefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptxCoefficient of Thermal Expansion and their Importance.pptx
Coefficient of Thermal Expansion and their Importance.pptx
 
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLSMANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
MANUFACTURING PROCESS-II UNIT-5 NC MACHINE TOOLS
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024Water Industry Process Automation & Control Monthly - April 2024
Water Industry Process Automation & Control Monthly - April 2024
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
KubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghlyKubeKraft presentation @CloudNativeHooghly
KubeKraft presentation @CloudNativeHooghly
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and Properties
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptx
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 

GraphQL the holy contract between client and server

  • 1. GraphQL the holy contract between 
 client and server
  • 4. Intro4 Client-server apps SERVER CLIENTS NodeJS C# .NET Go Java Python Ruby etc… Browsers iOS Android etc… MySQL MongoDB ES PostgreSQL Redis etc… HTTP WS HTML REST XML JSON etc… URL url-encoded form-data etc…
  • 6. Intro6 Drupal8 Schema (60 tables) SalesLogix Schema (168 tables) Wordpress 4.4.2 Schema (12 tables)
  • 7. Intro7 … and even more Monster with 333 tables Magento: Commerce Solutions for Selling Online (333 tables)Hi-Res: http://anna.voelkl.at/wp-content/uploads/2016/12/ce2.1.3.png Order table
 (138 fields)
  • 8. Intro8 How to create API 
 for this db-schema 
 HELL?
  • 9. Intro9 Wait! I have a better plan!
  • 10. GraphQL Basics10 Wikipedia MBT-70 schema This is GraphQL Schema
  • 12. GraphQL Basics12 GraphQL – is a … query 
 language
 for APIs query 
 executor
 on Schema for Frontenders for Backenders + NodeJS C# .NET Go Python Ruby etc…
  • 13. GraphQL Basics13 GraphQL Query Language GraphQL query Response in JSON
  • 14. GraphQL Basics14 GraphQL Query Language GraphQL query Response in JSON
  • 15. GraphQL Basics15 GraphQL Schema Query Mutation Subscription Type Single entrypoint READ (stateless) WRITE (stateless) EVENTS (stateful) GraphQL Schema Type Type
  • 16. GraphQL Basics16 Type Field 1 Field N Invoice id customerId amount Type Field Field Field date Field ObjectType Name Name
  • 17. GraphQL Basics17 Function with fetch logic from any data source Type Args Resolve Scalar or Object Type which returns resolve Set of input args for resolve function Description DeprecationReason Documentation Field hiding Type Field 1 Field N Field Config
  • 18. GraphQL Basics18 Invoice Customer id name id customerId amount 1 * Type Type Field Field Field Field Field date Field Int Int Int String Decimal Date Relations between types id
  • 19. GraphQL Basics19 Invoice Customer1* One does not simply draw a relation line in GraphQL!
  • 20. GraphQL Basics20 Invoice Customer id name id customerId amount Type Type Field Field Field Field Field customer invoices Field date Field select * from customer where 
 id = {invoice.customerId} select * from invoice where 
 customer_id = {customer.id} Field Resolve Resolve Customer Array<Invoice> Relation is a new field in your Type
  • 21. GraphQL Basics21 Invoice Customer id name id customerId amount Type Type Field Field Field Field Field invoices Field date Field select * from invoice where 
 customer_id = {customer.id} 
 limit {args.limit} Resolve Args Limit: 3 — Limit? Offset? Sort? Additional filtering? — No problem, add them to args and process in resolve function! Array<Invoice>
  • 22. GraphQL Basics22 function // fetch data logic (from any mix of DBs) // access logic (check permissions) ANY PRIVATE BUSINESS LOGIC… // processing logic (operations, calcs) source, args, context, info( ) { } return data; Resolve function
  • 23. GraphQL Basics23 ResolveJust remove and you get PUBLIC schema functions printSchema(schema); // txt output (SDL format)
 
 graphql(schema, introspectionQuery); // json output (AST) (private business logic) Schema Introspection
  • 24. GraphQL Basics24 • types • fields • args • docs • resolve • directives • input types • enums • interfaces • unions type Customer { 
 id: Int 
 name: String 
 # List of Invoices for current Customer 
 invoices(limit: Int): [Invoice] 
 } 
 
 # Show me the money
 type Invoice { 
 id: Int 
 customerId: Int 
 amount: Decimal
 # Customer data for current Invoice 
 customer: Customer 
 oldField: Int @deprecated(reason: "will be removed") 
 } SDL format (txt) Schema Introspection example
  • 25. GraphQL Basics25 an ability for awesome tooling: GraphiQL — graphical interactive in-browser GraphQL IDE Eslint-plugin-graphql — check queries in your editor, CI Relay-compiler — generates type definitions from queries • Autocompletion • Query validation • Documentation • Visualization • TypeDefs generation for static analysis (Flow, TypeScript) Schema Introspection provides
  • 26. GraphQL Basics26 const QueryType = new GraphQLObjectType({ 
 name: 'Query', 
 fields: () => ({ 
 films: { 
 type: new GraphQLList(FilmType), 
 args: { 
 limit: { type: GraphQLInt, defaultValue: 5 }, 
 }, 
 resolve: async (source, args) => { 
 const data = await loadData(`https://swapi.co/api/films/`); 
 return data.slice(0, args.limit); 
 }, 
 }, 
 ...otherFields, 
 }), 
 }); Type definition example
  • 27. GraphQL Basics27 const QueryType = new GraphQLObjectType({ 
 name: 'Query', 
 fields: () => ({ 
 films: { 
 type: new GraphQLList(FilmType), 
 args: { 
 limit: { type: GraphQLInt, defaultValue: 5 }, 
 }, 
 resolve: async (source, args) => { 
 const data = await loadData(`...`); 
 return data.slice(0, args.limit); 
 }, 
 }, 
 ...otherFields, 
 }), 
 }); Query Type type args resolve field FieldConfig Type Args Resolve Description DeprecationReason Type Field 1 Field N Type definition example
  • 28. GraphQL Basics28 • input types • directives • enums • interfaces • unions • fragments Don’t forget to read about http://graphql.org/learn/
  • 30. 30 REST API GraphQL Fetch sub-fetch 1 sub-fetch 2 sub-fetch N Network Delay Network Delay RESULT Query Network Delay RESULT - Sub-fetch logic on client side (increase bundle size) + Sub-fetch logic implemented on server side + No additional network round-trip (speed) - Over-fetching (redundant data transfer/parsing) + Exactly requested fields (speed)
  • 31. Intro31 A copy from one of the previous slides… Client-server apps SERVER CLIENTS NodeJS C# .NET Go Java Python Ruby etc… Browsers iOS Android etc… MySQL MongoDB ES PostgreSQL Redis etc… HTTP WS HTML REST XML JSON etc… URL url-encoded form-data etc…
  • 32. 32 GraphQL – is a query language for APIs NodeJS C# .NET Go Java PythonRuby etc… Browsers iOS Androidetc… MySQL MongoDB ES PostgreSQL Redis etc… HTTP WS etc… SERVER CLIENTS Specification for describing 
 the capabilities and requirements 
 of data models 
 for client‐server apps SCHEMA
 INTROSPECTION Pretty QUERY
 Language
  • 34. Static Analysis34 PRODUCTIVITY • Holy refactoring Static type checks 🚀 • Functions call checks • Types checks • Auto-suggestion Static program analysis is the analysis of computer software that is performed without actually executing programs
  • 35. Static Analysis35 Let’s turbo-charge 
 our client apps static analysis
 with GraphQL queries SERVER JS CLIENT File with
 GraphQL Query
 and Response processing GraphQL Schema
  • 36. Static Analysis36 SERVER JS CLIENT File with
 GraphQL Query
 and Response processing Schema Introspection GraphQL Schema 1
  • 37. Static Analysis37 Relay-compiler Apollo-codegen SERVER JS CLIENT File with
 GraphQL Query
 and Response processing Schema Introspection GraphQL Schema Watcher 1 2
  • 38. Static Analysis38 Hey, you have a wrong Query SERVER JS CLIENT File with
 GraphQL Query
 and Response processing Schema Introspection GraphQL Schema Watcher File with 
 Response Type Defs 1 2 3
  • 39. Static Analysis39 SERVER JS CLIENT File with
 GraphQL Query
 and Response processing Schema Introspection GraphQL Schema Watcher File with 
 Response Type Defs 1 2 3 4
  • 40. Static Analysis SERVER JS CLIENT File with
 GraphQL Query
 and Response processing Schema Introspection GraphQL Schema Watcher Flowtype File with 
 Response Type Defs 1 2 3 4 5 40 or TypeScript
  • 41. Static Analysis41 SERVER JS CLIENT File with
 GraphQL Query
 and Response processing Schema Introspection GraphQL Schema Watcher Flowtype File with 
 Response Type Defs 1 2 3 4 5 Houston, we have a Type Check problem at line 19287 col 5: possible undefined value 6
  • 42. Static Analysis42 GraphQL Query Generated Response Type Def Flow error Crappy Code DEMO Flow typed Code
  • 43. Static Analysis import { graphql } from 'react-relay'; 
 const query = graphql` 
 query BalanceQuery { 
 viewer { 
 cabinet { 
 accountBalance 
 } 
 } 
 }`; 43 GraphQL Query Balance.js JS CLIENT File with
 GraphQL Query
 and Response processing Watcher Flowtype File with 
 Response Type Defs 3 4 5
  • 44. Static Analysis /* @flow */ 
 /*:: 
 export type BalanceQueryResponse = {| 
 +viewer: ?{| 
 +cabinet: ?{| 
 +accountBalance: ?number; 
 |}; 
 |}; 
 |}; 
 */ 44 Generated Response Type Def Writer time: 0.53s [0.37s compiling, …] Created: - BalanceQuery.graphql.js Unchanged: 291 files Written default in 0.61s __generated__/BalanceQuery.graphql.js JS CLIENT File with
 GraphQL Query
 and Response processing Watcher Flowtype File with 
 Response Type Defs 3 4 5
  • 45. Static Analysis45 Crappy Codeimport { graphql } from 'react-relay'; 
 import * as React from 'react'; 
 
 export default class Balance extends React.Component { 
 render() { 
 const { viewer } = this.props; 
 return <div> Balance {viewer.cabinet.accountBalance} </div>; 
 } 
 } 
 const query = graphql`query BalanceQuery { 
 viewer { cabinet { accountBalance } } }`; Balance.js JS CLIENT File with
 GraphQL Query
 and Response processing Watcher Flowtype File with 
 Response Type Defs 3 4 5
  • 46. Static Analysis46 Flow typed Code
 import { graphql } from 'react-relay'; 
 import * as React from 'react'; 
 import type { BalanceQueryResponse } from './__generated__/BalanceQuery.graphql'; 
 
 type Props = BalanceQueryResponse; 
 export default class Balance extends React.Component<Props> { 
 render() { 
 const { viewer } = this.props; 
 return <div>Balance {viewer.cabinet.accountBalance}</div>; 
 } 
 } 
 const query = graphql`query BalanceQuery { 
 viewer { cabinet { accountBalance } } 
 }`; 
 
 Balance.js JS CLIENT File with
 GraphQL Query
 and Response processing Watcher Flowtype File with 
 Response Type Defs 3 4 5
  • 47. Static Analysis47 Flow typed Code/* @flow */ 
 import { graphql } from 'react-relay'; 
 import * as React from 'react'; 
 import type { BalanceQueryResponse } from './__generated__/BalanceQuery.graphql'; 
 
 type Props = BalanceQueryResponse; 
 export default class Balance extends React.Component<Props> { 
 render() { 
 const { viewer } = this.props; 
 return <div>Balance {viewer.cabinet.accountBalance}</div>; 
 } 
 } 
 const query = graphql`query BalanceQuery { 
 viewer { cabinet { accountBalance } } 
 }`; 
 
 Balance.js JS CLIENT File with
 GraphQL Query
 and Response processing Watcher Flowtype File with 
 Response Type Defs 3 4 5
  • 48. Static Analysis48 Error: src/_demo/Balance.js:11 11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>; ^^^^^^^ property `cabinet`. Property cannot be accessed on possibly null value 11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>; ^^^^^^ null Error: src/_demo/Balance.js:11 11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>; ^^^^^^^ property `cabinet`. Property cannot be accessed on possibly undefined value 11: return <div>Your balance: {viewer.cabinet.accountBalance}</div>; ^^^^^^ undefined Flow errors
  • 49. Static Analysis49 type Props = BalanceQueryResponse; class Balance extends React.Component<Props> { 
 render() { 
 const { viewer } = this.props; 
 return <div>{viewer.invoices}</div>; 
 } 
 } Flow errors for missing field
  • 50. Static Analysis50 Error: src/_demo/Balance.js:11 11: return <div>{viewer.invoices}</div>; ^^^^^^^^ property `invoices`. Property not found in v- 13: +viewer: ?{| 14: +cabinet: ?{| 15: +accountBalance: ?number; 16: |}; 17: |}; -^ object type. See: src/_demo/__generated__/ BalanceQuery.graphql.js:13 Flow errors for missing field
  • 52. GraphQL Query Problems52 Denial of Service attacks • pre-approve queries that the server can execute (persisted queries by unique ID) query HugeResponse { 
 user { 
 friends(limit: 1000) { 
 friends(limit: 1000) { 
 friends(limit: 1000) { 
 ... 
 } 
 } 
 } 
 } 
 } aka Resource exhaustion attaks • cost analysis on the query using by Facebook Solutions: • avoid nesting relations
  • 53. GraphQL Query Problems53 query NestedQueryN1 { 
 { 
 productList { 
 id 
 categoryId 
 category { 
 id 
 name 
 } 
 } 
 } 
 } N+1 query problem 1 query for 
 ProductList N queries 
 for fetching every 
 Category by id Solution: DataLoader const CatLoader = new DataLoader( ids => Category.findByIds(ids) ); 
 CatLoader.load(1); 
 CatLoader.load(2); 
 CatLoader.load(1); 
 CatLoader.load(4); will do just one BATCH request 
 on next tick to the Database
  • 55. Problem #1: too much copy/paste55 const QueryType = new GraphQLObjectType({ 
 name: 'Query', 
 fields: () => ({ 
 films: ..., 
 persons: ..., 
 planets: ..., 
 species: ..., 
 starships: ..., 
 vehicles: ..., 
 }), 
 }); 6 fields and every FieldConfig
 consists from 
 almost identical
 12 ctrl+c/ctrl+v lines Query Type example https://swapi.co The Star Wars API
  • 56. Problem #1: too much copy/paste56 films: { 
 type: new GraphQLList(FilmType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: async (source, args) => { 
 const data = await loadData(`https://swapi.co/api/films/`); 
 if (args && args.limit > 0) { 
 return data.slice(0, args.limit); 
 } 
 return data; 
 }, FieldConfig example for films field
  • 57. Problem #1: too much copy/paste { 
 films: { 
 type: new GraphQLList(FilmType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: async (source, args) => { 
 const data = await loadData(`https://swapi.co/api/films/`); 
 if (args && args.limit > 0) { 
 return data.slice(0, args.limit); 
 } 
 return data; 
 }, 
 }, 
 planets: { 
 type: new GraphQLList(PlanetType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: async (source, args) => { 
 const data = await loadData(`https://swapi.co/api/planets/`); 
 if (args && args.limit > 0) { 
 return data.slice(0, args.limit); 
 } 
 return data; 
 }, 
 }, 
 } 
 57 differs 
 only by url Comparison of two FieldConfigs
  • 58. Problem #1: too much copy/paste58 function createListResolve(url) { 
 return async (source, args) => { 
 const data = await loadData(url); 
 if (args && args.limit > 0) { 
 return data.slice(0, args.limit); 
 } 
 return data; 
 }; 
 } Solution 1: you may generate your resolve functions create a function 
 which returns a resolve function
  • 59. Problem #1: too much copy/paste 
 films: { 
 type: new GraphQLList(FilmType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: createListResolve(`https://swapi.co/api/films/`), 
 }, 
 
 planets: { 
 type: new GraphQLList(PlanetType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: createListResolve(`https://swapi.co/api/planets/`), 
 }, 
 { 
 films: { 
 type: new GraphQLList(FilmType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: async (source, args) => { 
 const data = await loadData(`https://swapi.co/api/films/`); 
 if (args && args.limit > 0) { 
 return data.slice(0, args.limit); 
 } 
 return data; 
 }, 
 }, 
 planets: { 
 type: new GraphQLList(PlanetType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: async (source, args) => { 
 const data = await loadData(`https://swapi.co/api/planets/`); 
 if (args && args.limit > 0) { 
 return data.slice(0, args.limit); 
 } 
 return data; 
 }, 
 }, 
 } 
 59 Solution 1: you may generate your resolve functions reduce N times 7 LoC to 1 LoC
  • 60. Problem #1: too much copy/paste 
 films: { 
 type: new GraphQLList(FilmType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: createListResolve(`https://swapi.co/api/films/`), 
 }, 
 
 planets: { 
 type: new GraphQLList(PlanetType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: createListResolve(`https://swapi.co/api/planets/`), 
 }, 
 60 Solution 2: you may generate your FieldConfigs differs only by `Type` and `url`
  • 61. Problem #1: too much copy/paste61 function createFieldConfigForList(type, url) { 
 return { 
 type: new GraphQLList(type), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: createListResolve(url), 
 }; 
 } Solution 2: you may generate your FieldConfigs create a function 
 which returns a FieldConfig
  • 62. Problem #1: too much copy/paste62 films: { 
 type: new GraphQLList(PlanetType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: createListResolve(`https://swapi.co/api/films/`), 
 }, 
 planets: { 
 type: new GraphQLList(FilmType), 
 args: { limit: { type: GraphQLInt, defaultValue: 5 } }, 
 resolve: createListResolve(`https://swapi.co/api/planets/`), 
 }, { 
 films: createFieldConfigForList(FilmType, `https://swapi.co/api/films/`), 
 planets: createFieldConfigForList(PlanetType, `https://swapi.co/api/planets/`), 
 } 10 LoC reduced to 2 LoC Solution 2: you may generate your FieldConfigs
  • 63. Problem #1: too much copy/paste63 DRY principle
 (don't repeat yourself) was
 reduced 
 in 3 times 90 LoC 30 LoC Solution 1: you may generate your resolve functions Solution 2: you may generate your FieldConfigs
  • 64. Problem #2: keep GraphQL types in sync with ORM/DB64 With time you may: • add new fields • change field types • remove fields • rename fields Model: User Type: User SYNC How to keep to Schemas in SYNC?
  • 65. Problem #2: keep GraphQL types in sync with ORM/DB65 GENERATE • via some cli/script • on server boot load (better) Solution: generate GraphQL types from ORM models SSOT principle (single source of truth) Model: User Type: User
  • 66. Problem #3: mess in types and resolve functions66 InvoiceType.js CustomerType.js id name id customerId amount customer invoices date select * from CUSTOMER 
 where … select * from INVOICE 
 where … Resolve Resolve InvoiceType.js contains CUSTOMER query CustomerType.js contains INVOICE query
  • 67. Problem #3: mess in types and resolve functions67 select * from INVOICES where … CustomerType.js id name invoices transactions tickets events likes messages … select * from TRANSACTIONS where … select * from TICKETS where … select * from EVENTS where … select * from LIKES where … select * from MESSAGES where … select * from … CustomerType.js knows too much 
 about queries of others types
  • 68. Problem #3: mess in types and resolve functions68 AdminNoteType.js id msg Customer Product Invoice … Resolve Resolve Resolve Resolve What if you need to restrict access for some group of users? Modify resolvers in all places?
  • 69. Problem #3: mess in types and resolve functions69 Solution: GraphQL Models* * “GraphQL Model” is not a part of GraphQL specification.
 
 It’s suggested additional layer of abstraction for more comfortable way to construct and maintain your schema and relations into it.
  • 70. Problem #3: mess in types and resolve functions 
 class CustomerGQLModel { 
 type: CustomerGraphQLType; 
 resolvers: { 
 findById: { 
 type: CustomerGraphQLType, 
 args: { id: 'Int!' }, 
 resolve: (_, args) => 
 load(`select * from customer where id = ${args.id}`), 
 }, 
 findMany: { ... }, 
 createOne: { ... }, 
 updateOne: { ... }, 
 removeOne: { ... }, 
 ... 
 }; 
 inputType: CustomerGraphQLInputType;
 } 
 
 70 1. type definition Contains: 2. all possible ways to CRUD data 3. may have other helper methods and data Type MAP<FieldConfig> InputType 1 2 3 Solution: GraphQL Models
  • 71. Problem #4: import { makeExecutableSchema } from ‘graphql-tools'; Writing Types via SDL and providing resolvers separately. 71 const schema = makeExecutableSchema({ typeDefs, resolvers }); 
 const typeDefs = ` 
 type Query { 
 customer(id: Int!): Customer invoices(limit: Int): [Invoice] 
 } 
 type Customer { 
 id: Int! 
 firstName: String 
 invoices: [Invoice] 
 }`; It’s nice developer experience for small to medium sized schema BUT… const resolvers = { 
 Query: { 
 customer: (_, { id }) => Customer.find({ id: id }), invoices: (_, { limit }) => Invoice.findMany({ limit }),
 }, 
 Customer: { 
 invoices: (source) => Invoice.find({ customerId: source.id }), 
 }, 
 }; type args resolve
  • 72. Problem #4: import { makeExecutableSchema } from ‘graphql-tools';72 • If one InputType used in several resolvers, then the complexity of refactoring increases dramatically. Hard to work with complex input args type Query { invoices(filter: FilterInput): [Invoice] 
 } 
 input FilterInput { 
 num: Int 
 dateRange: DateRangeInput
 status: InvoiceStatusEnum
 } input DateRangeInput { min: Date max: Date } enum InvoiceStatusEnum {
 unpaid paid declined
 } 
 invoices: (_, { filter }) => { 
 const { num, dateRange, status } = filter; 
 const q = {}; 
 if (num) q.num = num; 
 if (dateRange) q['date.$inRange'] = dateRange; 
 if (status) q.status = status; 
 return Post.findMany(q); 
 }, 
 • If one InputType per resolver, then too much 
 copy/paste almost similar types. All highlighted parts with red lines should be in sync * This example contains an error in the code, try to find it ;)
  • 73. Problem #4: import { makeExecutableSchema } from ‘graphql-tools'; Solution: build the schema programmatically Generate FieldConfigs via your custom functions (Resolvers) … 73 class InvoiceGQLModel { 
 findManyResolver(configOptions) { 
 return { 
 type: InvoiceType, 
 args: { 
 filter: { type: new GraphQLInputObjectType({ … })}, 
 }, 
 resolve: (_, args) => Invoice.findMany(args), 
 } } findByIdResolver() { … } … … and then … type args resolve
  • 74. Problem #4: import { makeExecutableSchema } from ‘graphql-tools';74 import { GraphQLSchema, GraphQLObjectType } from 'graphql'; 
 import InvoiceResolvers from './InvoiceResolvers'; 
 
 const schema = new GraphQLSchema({ 
 query: new GraphQLObjectType({ 
 name: 'Query', 
 fields: { 
 invoices: InvoiceResolvers.findManyResolver(), 
 ... 
 }, 
 }), 
 }); http://graphql.org/graphql-js/constructing-types/ Solution: build the schema programmatically …and then build your Schema from fields and your Resolvers
  • 75. Problem #4: import { makeExecutableSchema } from ‘graphql-tools';75 type Query { invoices(filter: FilterInput): [Invoice] 
 } 
 invoices: (_, { filter }) => { … }
 { 
 type: new GraphQLList(Invoice), 
 args: { 
 filter: { type: new GraphQLInputObjectType({ … })}, 
 }, 
 resolve: (_, { filter }) => { … }, 
 } combine code from different places
 back to FieldConfig type args resolve type args resolve
  • 76. Problem #4: import { makeExecutableSchema } from ‘graphql-tools';76 type Query { invoices(filter: FilterInput): [Invoice] 
 } 
 invoices: (_, { filter }) => { … }
 { 
 type: [Invoice], 
 args: { 
 filter: `input FilterInput { … }`, 
 }, 
 resolve: (_, { filter }) => { … }, 
 } my code with
 graphql-compose combine code from different places
 back to FieldConfig
  • 78. graphql-compose packages78 Graphql-compose-* The main idea is to generate GraphQL Schema from your ORM/Mappings at the server startup with a small lines of code as possible. — OSS packages family 
 for generating GraphQL Types MIT License Exposes Flowtype/Typescript declarations With awful docs all packages have more than 460 starts on GitHub Help wanted
  • 79. graphql-compose packages Graphql-compose 79 It bundles your Schema webpackworks almost like a from different type sources
  • 80. graphql-compose packages80 ORM Schema, Mapping TypeComposer
 with Resolvers GraphQL Schema Generate editable GraphQL Types
 with a set of CRUD Resolvers (FieldConfigs w/ args, type, resolve) Remove/add fields
 Wrap default Resolvers with custom business logic
 Create own Resolvers (FieldConfigs)
 Build relations between types Manually created TypeComposers
 or Vanilla GraphQL types 1 2 3 Schema creation workflow
  • 81. graphql-compose packages81 const InvoiceItemTC = TypeComposer.create(` 
 type InvoiceItem { 
 description: String 
 qty: Int 
 price: Float 
 } 
 `); SDL syntax for simple types (schema definition language) Graphql-compose provides handy syntax for manual type creation
  • 82. graphql-compose packages82 const InvoiceTC = TypeComposer.create({ 
 name: 'Invoice', 
 fields: { 
 id: 'Int!', 
 now: { 
 type: 'Date', 
 resolve: () => Date.now() 
 }, items: () => [InvoiceItemTC], 
 }, 
 }); SDL syntax inside Type as function, [ ] as List Config Object Syntax for complex types Graphql-compose provides handy syntax for manual type creation
  • 83. graphql-compose packages83 TC.hasField('lon'); // boolean 
 TC.getFieldNames(); // ['lon', 'lat'] 
 TC.getField('lon'); // FieldConfig 
 TC.getField('lon'); // return FieldConfig 
 TC.getFields(); // { lon: FieldConfig, lat: FieldConfig } TC.setFields({ ... }); // completely replace all fields 
 TC.setField('lon', { ... }); // replace `lon` field with new FieldConfig 
 TC.removeField('lon'); TC.removeOtherFields(['lon', 'lat']); // will remove all other fields 
 TC.reorderFields(['lat', 'lon']); // reorder fields, lat becomes first 
 TC.deprecateFields({ 'lat': 'deprecation reason' }); // mark field as deprecated TC.getFieldType('lat'); // GraphQLFloat 
 TC.getFieldTC('complexField'); // TypeComposer 
 TC.getFieldArgs('lat'); // returns map of args config or empty {} if no args 
 TC.hasFieldArg('lat', 'arg1'); // false 
 TC.getFieldArg('lat', 'arg1'); // returns arg config TC.addFields({ field1: …, field2: … }); 
 TC.removeField(['field2', ‘field3']); TC.extendField('lat', { description: 'Latitude', resolve: () => {} }); TOP 3 commonly 
 used methods Bunch of other 
 useful methods Graphql-compose provides methods 
 for modifying Types
  • 84. graphql-compose packages84 InvoiceTC.addField('items', { 
 type: () => ItemsTC, 
 resolve: (source) => { 
 return Items.find({ invoiceId: source.id }) 
 }, 
 }); Graphql-compose create relations between Types via FieldConfig Type as function
 solves hoisting problems
  • 85. graphql-compose packages85 InvoiceTC.addRelation('items', { 
 resolver: () => ItemsTC.getResolver('findMany'), 
 prepareArgs: { 
 filter: source => ({ invoiceId: source.id }), 
 }, 
 }); Graphql-compose create relations between Types via Resolvers Prepare args for Resolver
  • 86. graphql-compose packages86 graphql-compose-mongoose graphql-compose-json graphql-compose-elasticsearch graphql-compose-pagination graphql-compose-connection graphql-compose-relay type generator resolver generator type/resolver modifier Graphql-compose is a great tool for writing your own type generators/plugins type generator resolver generator resolver generator type generator resolver generator http API wrapper graphql-compose-aws SDK API wrapper🌶
  • 87. graphql-compose packages87 graphql-compose-aws ~700 lines of code, 2 days of work generates more than 10 000 GraphQL Types schema size ~2 Mb in SDL, ~9 Mb in json Huge GraphQL Schema example JUST IN 2 DAYS
  • 88. graphql-compose packages88 125 Services 3857 Operations 6711 Input/Output params https://graphqlbin.com/plqhO AWS Cloud API in GraphQL Schema generation takes about ~1-2 seconds
  • 89. graphql-compose packages89 https://github.com/nodkz/graphql-compose-examples https://github.com/lyskos97/graphql-compose-swapi Mongoose, Elastic, Northwind Wrapping REST API Graphql-compose schema demos https://graphql-compose.herokuapp.com https://graphql-compose-swapi.herokuapp.com
  • 91. 91 GraphQL less network traffic less time on coding less errors less stress more success is awesome! 👍 PS. SOMETIMES A LOT LESS
  • 93. 93 Take away! GraphQL is powerful query language 
 with great tools GraphQL is typed so it helps with 
 static analysis on clients Generate GraphQL Schemas on server
  • 95. 95 GraphQL is a server and client apps for your