GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7714989/pasted-from-clipboard.png)
GraphQL in 2020
Who am I
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7188101/pasted-from-clipboard.png)
Lead Sr. Software Engineer at Double
Big fan and user of GraphQL since 4 years
Charly POLY
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715022/pasted-from-clipboard.png)
GraphQL in 2020
GraphQL in 1'
{
project(name: "GraphQL") {
tagline
}
}
{
"project": {
"tagline": "A query language for APIs"
}
}
type Project {
name: String
tagline: String
contributors: [User]
}
type Query {
project(name: String!): Project
}
const resolvers = {
Query: {
project: (parent, args, context, info) => (
projects.find(p => p.name === args.name)
),
},
};
1. Schema
2. Resolvers
3. Query
4. JSON data
GraphQL in 2020
GraphQL in 2015
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715110/pasted-from-clipboard.png)
initial public release
server: graphql@0.0.2 (+ express)
client: relay@0.1.0
GraphQL in 2020
GraphQL in 2015
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715110/pasted-from-clipboard.png)
initial public release
server: graphql@0.0.2 (+ express)
import {
graphql,
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
} from 'graphql';
var schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'RootQueryType',
fields: {
hello: {
type: GraphQLString,
resolve() {
return 'world';
},
},
},
}),
});
GraphQL in 2020
GraphQL in 2016
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715110/pasted-from-clipboard.png)
Ecosystem awakening
graphql-tools
apollo-server
apollo-client (+ react-apollo)
graphiql
Libraries to boost development
GraphQL in 2020
GraphQL in 2016
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715110/pasted-from-clipboard.png)
Ecosystem awakening
graphql-tools
import { makeExecutableSchema } from '@graphql-tools/schema';
const resolvers = /*...*/
const typeDefs = `
# ...
schema {
query: Query
mutation: Mutation
}
`;
const executableSchema = makeExecutableSchema({
typeDefs,
resolvers,
});
GraphQL in 2020
GraphQL in 2016 - intermission
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715257/pasted-from-clipboard.png)
GraphQL in 2020
GraphQL in 2018 - intermission
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7246900/pasted-from-clipboard.png)
GraphQL in 2020
GraphQL in 2018 - intermission
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7246900/pasted-from-clipboard.png)
-
Build smooth user-experiences
"Ask for what you want", optimistic UIs
-
Solve data-complexity issue on front-end side
Apollo cache, typed mutations, DDD APIs
-
Microservices orchestration
Apollo schema stitching ➡️ Apollo Federation
GraphQL in 2020
GraphQL in 2018
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715110/pasted-from-clipboard.png)
Ecosystem on the rise
Libraries: Apollo, Relay
Concepts: Schema stitching, client cache, optimistic UI patterns
Services: AWS App Sync, Apollo Optics, Prisma
Faster and more robust development
GraphQL in 2020
GraphQL in 2018
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715110/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715233/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715237/pasted-from-clipboard.png)
First public GraphQL APIs
GraphQL in 2020
GraphQL in 2019
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715052/pasted-from-clipboard.png)
State of JS 2019
GraphQL in 2020
GraphQL in 2020?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
Apollo Federation
Hasura
GraphQL Mesh
Prisma
GraphQL Engine
Apollo State management
DGraph
TypeGraphQL
graphqless
GraphCMS
Gatsby
AWS AppSync
Relay
Hasura
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715219/pasted-from-clipboard.png)
GraphQL Code Generator
GraphQL modules
Apollo Platform
urql
GraphQL in 2020
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL is much more than an efficient way of fetching data from the client side
GraphQL in 2020
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL is much more than an efficient way of fetching data from the client side
1. The GraphQL innovations on front-end side
2. GraphQL bridging the gaps on server-side
The GraphQL innovations on front-end side
GraphQL as state management
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7250699/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7250707/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7250709/pasted-from-clipboard.png)
Recoil
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL is a "data query and manipulation language for APIs"
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7727791/pasted-from-clipboard.png)
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
- Apollo Client 1 & 2: build the best GraphQL Client
- Apollo Client 3: a library for interacting with a client-side data graph
Apollo Client mission
Local state management with GraphQL
GraphQL in 2020
GraphQL as state management
Simple local state example
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
import { TypePolicies, makeVar } from '@apollo/client';
export const DARK_MODE_KEY = 'dark-mode'
export const darkMode = makeVar<boolean>(localStorage.getItem(DARK_MODE_KEY) || false)
export const resolvers: TypePolicies = {
Query: {
fields: {
darkMode: {
read: () => darkMode(),
},
},
},
};
export default resolvers
const { data } = useQuery(`
query isDarkMode {
darkMode @client
}
`)
Example: darkMode settings
GraphQL in 2020
GraphQL as state management
import { TypePolicies, makeVar } from '@apollo/client';
export const DARK_MODE_KEY = 'dark-mode'
export const darkMode = makeVar<boolean>(localStorage.getItem(DARK_MODE_KEY) || false)
export const resolvers: TypePolicies = {
Query: {
fields: {
darkMode: {
read: () => darkMode(),
},
},
},
};
export default resolvers
darkMode(true)
updates
useQuery() hook
Example: darkMode settings
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
import { darkMode, DARK_MODE_KEY } from './resolvers'
const useUpdateDarkMode = () => useCallback(
(enabled: boolean) => {
localStorage.setItem(DARK_MODE_KEY, enabled)
darkMode(enabled)
},
[],
)
export default useUpdateDarkMode
Example: darkMode settings
GraphQL in 2020
GraphQL as state management
More advanced local state example
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7718108/todoDraft.gif)
- TodoList items are remote (GQL API)
- The newly created Todo is local
- Totally transparent at component- level
const { data, error } = useMainTopicListQuery()
// data contains remote + local todos
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
Adding the TodoDraft to the list Query
Apollo Cache
TypePolicies read()
functions
useQuery() hooks
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
1. Adding the TodoDraft to the list Query
const { data } = useQuery(`
query getMainTopicList($completedAfter: DateTime!) {
activeTopics: topicsList(first: 200, view: ACTIVE) {
hasAfter
items {
...TopicListItem
}
}
}
`)
const typePolicies: TypePolicies = {
Query: {
fields: {
topicsList: {
keyArgs: ['view', 'first'],
// ...
read: (existing, { args }) => {
const draft = todoDrafts()
return draft ?
{
...existing,
items: [
draft,
...(existing ? existing.items : []),
],
}:
existing
},
},
},
},
}
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
2. Todo `isDraft` local property
fragment TodoListItem on Todo {
id
reference
title
# ...
isDraft @client
# ...
}
export const resolvers: TypePolicies = {
// we augment the `Todo` type
Todo: {
fields: {
isDraft: {
read: (existing = false, { readField }) => isDraft(readField('id')),
},
},
},
};
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7718108/todoDraft.gif)
GraphQL in 2020
GraphQL as state management
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
Full local state management capabilities
- State: managed by ApolloCache, along side with APIs data
- Computed values: TypePolicies
- Actions: reactive variables or client.writeQuery()
- Reactions: Apollo ObservableQuery + reactive variables
- Tools: Apollo Client Dev tools
The GraphQL innovations on front-end side
GraphQL Full-stack type safety
GraphQL in 2020
GraphQL Full-stack type safety
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL introspection is a core
- most underrated - feature of the language
GraphQL in 2020
GraphQL Full-stack type safety
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
{
__schema {
types {
name
kind
fields {
name
type {
name
ofType {
name
}
}
}
}
}
}
{
"data": {
"__schema": {
"types": [
{
"name": "Query",
/* ... */
},
{
"name": "PrivateUser",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "birthday",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "country",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "display_name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "email",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "product",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "tracks",
"type": {
"name": null,
"ofType": {
"name": "SavedTrack"
}
}
},
{
"name": "playlists",
"type": {
"name": null,
"ofType": {
"name": "Playlist"
}
}
},
{
"name": "albums",
"type": {
"name": null,
"ofType": {
"name": "SavedAlbum"
}
}
},
{
"name": "top_artists",
"type": {
"name": null,
"ofType": {
"name": "Artist"
}
}
},
{
"name": "top_tracks",
"type": {
"name": null,
"ofType": {
"name": "Track"
}
}
},
{
"name": "images",
"type": {
"name": null,
"ofType": {
"name": "Image"
}
}
},
{
"name": "artists",
"type": {
"name": null,
"ofType": {
"name": "Artist"
}
}
},
{
"name": "devices",
"type": {
"name": null,
"ofType": {
"name": "Device"
}
}
},
{
"name": "player",
"type": {
"name": "Player",
"ofType": null
}
}
]
},
{
"name": "String",
"kind": "SCALAR",
"fields": null
},
{
"name": "Int",
"kind": "SCALAR",
"fields": null
},
{
"name": "SavedTrack",
"kind": "OBJECT",
"fields": [
{
"name": "added_at",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "track",
"type": {
"name": "Track",
"ofType": null
}
}
]
},
{
"name": "Track",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "album",
"type": {
"name": "Album",
"ofType": null
}
},
{
"name": "artists",
"type": {
"name": null,
"ofType": {
"name": "Artist"
}
}
},
{
"name": "available_markets",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "audio_features",
"type": {
"name": "AudioFeatures",
"ofType": null
}
},
{
"name": "disc_number",
"type": {
"name": "Int",
"ofType": null
}
},
{
"name": "duration_ms",
"type": {
"name": "Int",
"ofType": null
}
},
{
"name": "explicit",
"type": {
"name": "Boolean",
"ofType": null
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "is_playable",
"type": {
"name": "Boolean",
"ofType": null
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "popularity",
"type": {
"name": "Int",
"ofType": null
}
},
{
"name": "preview_url",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "track_number",
"type": {
"name": "Int",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
}
]
},
{
"name": "Album",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "album_type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "artists",
"type": {
"name": null,
"ofType": {
"name": "Artist"
}
}
},
{
"name": "available_markets",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "genres",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "label",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "popularity",
"type": {
"name": "Int",
"ofType": null
}
},
{
"name": "release_date",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "release_date_precision",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "images",
"type": {
"name": null,
"ofType": {
"name": "Image"
}
}
},
{
"name": "tracks",
"type": {
"name": null,
"ofType": {
"name": "Track"
}
}
}
]
},
{
"name": "Artist",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "genres",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "popularity",
"type": {
"name": "Int",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "images",
"type": {
"name": null,
"ofType": {
"name": "Image"
}
}
},
{
"name": "top_tracks",
"type": {
"name": null,
"ofType": {
"name": "Track"
}
}
},
{
"name": "albums",
"type": {
"name": null,
"ofType": {
"name": "Album"
}
}
},
{
"name": "related_artists",
"type": {
"name": null,
"ofType": {
"name": "Artist"
}
}
}
]
},
{
"name": "Image",
"kind": "OBJECT",
"fields": [
{
"name": "height",
"type": {
"name": "Int",
"ofType": null
}
},
{
"name": "url",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "width",
"type": {
"name": "Int",
"ofType": null
}
}
]
},
{
"name": "AudioFeatures",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "acousticness",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "analysis_url",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "danceability",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "duration_ms",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "energy",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "instrumentalness",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "key",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "liveness",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "loudness",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "mode",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "speechiness",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "tempo",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "time_signature",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "track_href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "valence",
"type": {
"name": "String",
"ofType": null
}
}
]
},
{
"name": "Boolean",
"kind": "SCALAR",
"fields": null
},
{
"name": "Playlist",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "description",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "owner",
"type": {
"name": "PublicUser",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "tracks",
"type": {
"name": null,
"ofType": {
"name": "PlaylistTrack"
}
}
},
{
"name": "public",
"type": {
"name": "Boolean",
"ofType": null
}
},
{
"name": "images",
"type": {
"name": null,
"ofType": {
"name": "Image"
}
}
}
]
},
{
"name": "PublicUser",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "display_name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "playlists",
"type": {
"name": null,
"ofType": {
"name": "Playlist"
}
}
},
{
"name": "images",
"type": {
"name": null,
"ofType": {
"name": "Image"
}
}
}
]
},
{
"name": "PlaylistTrack",
"kind": "OBJECT",
"fields": [
{
"name": "added_at",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "track",
"type": {
"name": "Track",
"ofType": null
}
},
{
"name": "added_by",
"type": {
"name": "PublicUser",
"ofType": null
}
},
{
"name": "is_local",
"type": {
"name": "Boolean",
"ofType": null
}
}
]
},
{
"name": "SavedAlbum",
"kind": "OBJECT",
"fields": [
{
"name": "added_at",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "album",
"type": {
"name": "Album",
"ofType": null
}
}
]
},
{
"name": "Device",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "is_active",
"type": {
"name": "Boolean",
"ofType": null
}
},
{
"name": "is_restricted",
"type": {
"name": "Boolean",
"ofType": null
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "volume_percent",
"type": {
"name": "Int",
"ofType": null
}
}
]
},
{
"name": "Player",
"kind": "OBJECT",
"fields": [
{
"name": "timestamp",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "device",
"type": {
"name": "Device",
"ofType": null
}
},
{
"name": "progress_ms",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "is_playing",
"type": {
"name": "Boolean",
"ofType": null
}
},
{
"name": "shuffle_state",
"type": {
"name": "Boolean",
"ofType": null
}
},
{
"name": "repeat_state",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "item",
"type": {
"name": "Track",
"ofType": null
}
},
{
"name": "context",
"type": {
"name": "PlayerContext",
"ofType": null
}
}
]
},
{
"name": "PlayerContext",
"kind": "OBJECT",
"fields": [
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
}
]
},
{
"name": "__Schema",
"kind": "OBJECT",
"fields": [
{
"name": "types",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "queryType",
"type": {
"name": null,
"ofType": {
"name": "__Type"
}
}
},
{
"name": "mutationType",
"type": {
"name": "__Type",
"ofType": null
}
},
{
"name": "subscriptionType",
"type": {
"name": "__Type",
"ofType": null
}
},
{
"name": "directives",
"type": {
"name": null,
"ofType": {
"name": null
}
}
}
]
},
{
"name": "__Type",
"kind": "OBJECT",
"fields": [
{
"name": "kind",
"type": {
"name": null,
"ofType": {
"name": "__TypeKind"
}
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "description",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "fields",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "interfaces",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "possibleTypes",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "enumValues",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "inputFields",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "ofType",
"type": {
"name": "__Type",
"ofType": null
}
}
]
},
{
"name": "__TypeKind",
"kind": "ENUM",
"fields": null
},
{
"name": "__Field",
"kind": "OBJECT",
"fields": [
{
"name": "name",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "description",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "args",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "type",
"type": {
"name": null,
"ofType": {
"name": "__Type"
}
}
},
{
"name": "isDeprecated",
"type": {
"name": null,
"ofType": {
"name": "Boolean"
}
}
},
{
"name": "deprecationReason",
"type": {
"name": "String",
"ofType": null
}
}
]
},
{
"name": "__InputValue",
"kind": "OBJECT",
"fields": [
{
"name": "name",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "description",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": null,
"ofType": {
"name": "__Type"
}
}
},
{
"name": "defaultValue",
"type": {
"name": "String",
"ofType": null
}
}
]
},
{
"name": "__EnumValue",
"kind": "OBJECT",
"fields": [
{
"name": "name",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "description",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "isDeprecated",
"type": {
"name": null,
"ofType": {
"name": "Boolean"
}
}
},
{
"name": "deprecationReason",
"type": {
"name": "String",
"ofType": null
}
}
]
},
{
"name": "__Directive",
"kind": "OBJECT",
"fields": [
{
"name": "name",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "description",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "locations",
"type": {
"name": null,
"ofType": {
"name": null
}
}
},
{
"name": "args",
"type": {
"name": null,
"ofType": {
"name": null
}
}
}
]
},
{
"name": "__DirectiveLocation",
"kind": "ENUM",
"fields": null
},
{
"name": "SimplifiedArtist",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
}
]
},
{
"name": "SimplifiedAlbum",
"kind": "OBJECT",
"fields": [
{
"name": "id",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "album_type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "artists",
"type": {
"name": null,
"ofType": {
"name": "Artist"
}
}
},
{
"name": "available_markets",
"type": {
"name": null,
"ofType": {
"name": "String"
}
}
},
{
"name": "href",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "label",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "name",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "type",
"type": {
"name": "String",
"ofType": null
}
},
{
"name": "uri",
"type": {
"name": "String",
"ofType": null
}
}
]
}
]
}
}
}
GraphQL in 2020
GraphQL Full-stack type safety
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7251081/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7251082/pasted-from-clipboard.png)
GraphQL in 2020
GraphQL Full-stack type safety
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7251104/pasted-from-clipboard.png)
Given a GraphQL Schema, generates:
- TypeScript types definition
- React Apollo hooks definition
- urql components
- Types for Flow, Java, Kotlin
GraphQL in 2020
GraphQL Full-stack type safety
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
Typed React hooks generations
GraphQL in 2020
GraphQL Full-stack type safety
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
`TypedDocumentNode` for simplicity
GraphQL in 2020
GraphQL Full-stack type safety
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
We now have 'cheap to maintain'
best-in-class TypeScript types in our front-end
GraphQL in 2020
GraphQL (Beyond type safety intermission)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL in 2020
GraphQL (Beyond type safety intermission)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
Better front-end developer experience
-
GraphQL without queries
-
GraphQL forms
GraphQL in 2020
GraphQL (Beyond type safety intermission)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL without queries: gqless
const User = graphql(({ user }: { user: User }) => (
<div>
<h2>{user.name}</h2>
<img src={user.avatarUrl({ size: 100 })} />
</div>
))
const App = graphql(() => (
<div>
{query.users.map(user => (
<User key={user.id} user={user} />
))}
</div>
))
query App {
users {
id
name
avatarUrl(size: 100)
}
}
+ TypeScript support
GraphQL in 2020
GraphQL (Beyond type safety intermission)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL forms: Frontier
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7251076/pasted-from-clipboard.png)
import gql from "graphql-tag";
import { Frontier } from "frontier-forms";
import { myApplicationKit } from "./uiKit";
import { client } from "./apollo-client";
const mutation = gql`
mutation($user: User!) {
createUser(user: $user) { id }
}
`;
<Frontier
client={client}
mutation={mutation}
uiKit={myApplicationKit}
/>
GraphQL bridging the gaps on server-side
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722060/pasted-from-clipboard.png)
Apollo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722061/pasted-from-clipboard.png)
Prisma
AWS AppSync
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722064/pasted-from-clipboard.png)
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
Apollo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722061/pasted-from-clipboard.png)
Prisma
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722064/pasted-from-clipboard.png)
- What about more complex GraphQL APIs without a from-scratch development?
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
Apollo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722061/pasted-from-clipboard.png)
Prisma
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722064/pasted-from-clipboard.png)
Hasura
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722087/pasted-from-clipboard.png)
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
Hasura
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7251069/realtime-4de82190c831ba75fa0de92e4d54c64c.gif)
Hasura translate GraphQL AST to SQL AST,
providing blazing fast execution with minimum configuration
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
Hasura
Custom logic support via Actions
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722103/pasted-from-clipboard.png)
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
Hasura
- ACL support
- Authentication / Authorization (JWT)
- Remote schemas support (schema stitching)
- Subscriptions support
- Actions for custom logic
- Trigger webhooks on database events
- Bonus: one-click install on most cloud providers
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
Apollo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722061/pasted-from-clipboard.png)
Prisma
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722064/pasted-from-clipboard.png)
- What about old REST APIs and external services?
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL bridging the gaps on server-side
Apollo
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722061/pasted-from-clipboard.png)
Prisma
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722064/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722091/pasted-from-clipboard.png)
GraphQL Mesh
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL Mesh
GraphQL bridging the gaps on server-side
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722091/pasted-from-clipboard.png)
GraphQL Mesh leverages API definition standards to transform existing API to GraphQL APIs
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL Mesh
GraphQL bridging the gaps on server-side
Spotify GraphQL in 5'
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7715257/pasted-from-clipboard.png)
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL Mesh
GraphQL bridging the gaps on server-side
Spotify GraphQL in 5'
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722145/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722154/pasted-from-clipboard.png)
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL Mesh
GraphQL bridging the gaps on server-side
Spotify GraphQL in 5'
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7722150/pasted-from-clipboard.png)
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL Mesh
GraphQL bridging the gaps on server-side
- GraphQL proxy over your data
- Schema transformation
- Resolvers composition
- Caching
- SDK generation
GraphQL Mesh doesn’t aim to create [...] public GraphQL schema [...], you should consider implementing another layer that exposes your public data [...].
GraphQL in 2020
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
GraphQL API building in 2020
- Apollo, Prisma, and AWS AppSync are not unique solutions
- Hasura helps you build performant and powerful API
- GraphQL Mesh brings you universal GraphQL
GraphQL bridging the gaps on server-side
GraphQL in 2020
GraphQL in 2020 ⚡️
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
Wrap-up
GraphQL in 2020
GraphQL in 2020 ⚡️
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
- The Guild
- Hasura
- Dgraph
- and many more individual contributors!
Beyond a "Facebook & Apollo technology"
GraphQL in 2020
GraphQL in 2020 ⚡️
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
- Better front-end developer experience (Full-stack type safety, ...)
- Easier complex GraphQL API building (Hasura)
- Fast GraphQL Database (Dgraph, Hasura)
- GraphQL as a universal data language (state, GraphQL Mesh)
Beyond fetching data from the client-side
GraphQL in 2020
GraphQL: Looking forward
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
- Subscriptions / Async evolutions
- Apollo 3, Hasura
- @defer, @live
- Smarter client-side cache?
- Better mobile clients ecosystem?
- more public APIs?
GraphQL in 2021?
Thank you!
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075490/5841c47ba6515b1e0ad75aa3.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/5075491/580b57fcd9996e24bc43c53e.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/245259/images/7189412/pasted-from-clipboard.png)
graphql-in-2020
By Charly Poly
graphql-in-2020
- 1,397