graphql, l'avenir du rest ?

Post on 29-Jan-2018

765 Views

Category:

Internet

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

G R A P H Q L , L’ AV E N I R D U R E S T ?

F R A N Ç O I S Z A N I N O T T O - @ f r a n c o i s z

G R A P H Q Lg r a f kɥɛ l

G R A S K A F K A E C U E L L E

L E P R O B L È M E

PA R T I E 1 / 6

R E S T

1. GET /user

2. GET /tweets

3. GET /users?ids=[123,456,789,…]

4. GET /tweet_stats?ids=[123,456,789,…]

5. GET /notifications

6. POST /views

B R E A K I N G C H A N G E

R E S T I N P E A C E

• Trop de requêtes par page

• Mauvaise performance sur mobile

• Pas de standard

• Pas de schema

• Evolution impossible

• Actions limitées au CRUD

L E S A U T R E S C A N D I D AT S

PA R T I E 2 / 6

R E S T + +

GET /tweets?include=author&fields=[id,date,body]

S Q L O V E R H T T P

GET /data?query=SELECT t.id, t.date,t.body,a.nameFROM tweets t LEFT JOIN author a ON tweet.author_id = author.id

LIMIT 10

P R O T O C O L B U F F E R S

FA L C O R

L E S A I N T G R A A L

• Langage de requêtage déclaratif

• Reposant sur du Remote Procedure Call

• Typage fort, schema

• Support des agrégats

• Standardisé

• Non lié à HTTP

D É C O U V R E Z G R A P H Q L

PA R T I E 3 / 6

POST / HTTP 1.1 Host: http://graphql.acme.com/ Content-Type: application/graphql { getTweet(id: 123) { id body date } }

HTTP/1.1 200 OK { "data": { "getTweet": { "id": "123", "body": "Lorem Ipsum", "date": "2017-07-14" } } }

GET /tweets/123 HTTP 1.1 Host: http://rest.acme.com/

HTTP/1.1 200 OK { "id": 123, "body": "Lorem Ipsum", "user_id": 456, "views": 45, "date": "2017-07-14", // etc. }

Req

uête

Rép

ons

e

REST GraphQL

POST / HTTP 1.1 Host: http://graphql.acme.com/ Content-Type: application/graphql { getTweets(limit: 10, sortField: "date", sortOrder: "DESC") { id body date } getUser { fullName } getNotificationsMeta { count } }

Req

uête

HTTP/1.1 200 OK Content-Type: application/json { "data": { "getTweets": [ { "id": "752", "body": "The guy next to me is listening...", "date": "2017-07-15T13:17:42.772Z", }, { "id": "123", "body": "The Espionnage Act was designed to...", "date": "2017-07-14T12:44:17.449Z" }, // etc. ], "getUser": { "fullName": "John Doe" }, "getNotificationsMeta": { "count": 12 } } }

Rép

ons

e

POST / HTTP 1.1 Host: http://graphql.acme.com/ Content-Type: application/graphql { getTweets(limit: 10, sortField: "date", sortOrder: "DESC") { id body date Author { username fullName avatarUrl } Stat { nbResponses nbRetweets nbLikes } } getUser { fullName } getNotificationsMeta { count } }

Req

uête

POST / HTTP 1.1 Host: http://graphql.acme.com/ Content-Type: application/graphql { getTweets(limit: 10, sortField: "date", sortOrder: "DESC") { id body date Author { username fullName avatarUrl } Stat { nbResponses nbRetweets nbLikes } } getUser { fullName } getNotificationsMeta { count } }

Req

uête

{ "data": { "getTweets": [ { "id": "752", "body": "The guy next to me is listening...", "date": "2017-07-15T13:17:42.772Z", "Author": { "username": "quantian1", "fullName": "Quantian", "avatarUrl": "https://amce.com/avatars/34345745634", }, "Stat": { "nbResponses": 3 "nbRetweets": 4, "nbLikes": 40 } }, // etc. ], "getUser": { "fullName": "John Doe" }, "getNotificationsMeta": { "count": 12 } } }

Rép

ons

e

POST / HTTP 1.1 Host: http://graphql.acme.com/ Content-Type: application/graphql { getTweets(limit: 10, sortField: "date", sortOrder: "DESC") { id body date Author { username fullName avatarUrl } Stat { nbResponses nbRetweets nbLikes } } getUser { fullName } getNotificationsMeta { count } }

Req

uête

# entry points type Query { getTweet(id: ID!): Tweet getTweets(limit: Int, sortField: String, sortOrder: String): [Tweet] getUser: User getNotificationsMeta: Meta }

# custom types type Tweet { id: ID! body: String date: Date Author: User Stats: Stat }

type User { id: ID! username: String firstName: String lastName: String fullName: String name: String @deprecated avatarUrl: Url

# entry points type Query { getTweet(id: ID!): Tweet getTweets(limit: Int, sortField: String, sortOrder: String): [Tweet] getUser: User getNotificationsMeta: Meta }

# custom types type Tweet { id: ID! body: String date: Date Author: User Stats: Stat }

type User { id: ID! username: String firstName: String lastName: String fullName: String name: String @deprecated avatarUrl: Url

POST / HTTP 1.1 Host: http://graphql.acme.com/ Content-Type: application/graphql { getTweets(limit: 10, sortField: "date", sortOrder: "DESC") { id body date(timezone: "UTC +2") Author { username fullName avatarUrl TopTweets(limit: 10) { body date(timezone: "UTC +2 ») Stats { nbResponses nbRetweets } } } Stat { nbResponses nbRetweets } } }

Req

uête

L E L A N G A G E G R A P H Q L

• Types

• Champs

• Requêtes, Mutations, Abonnements

• Variables

• Fragments

• Directives

C O M M E N T G R A P H Q L R É P O N D A V O S D E M A N D E S

PA R T I E 4 / 6

type Query { getTweet(id: ID!): Tweet getTweets(limit: Int): [Tweet] } type Tweet { id: ID! body: String Author: User } type User { fullName: String }

const resolvers = { Query: { getTweet: (_, params) => tweets.find(t => t.id == params.id), getTweets: (_, params) => tweets.slice(0, params.limit), }, Tweet: { id: tweet => tweet.id, body: tweet => tweet.body, Author: tweet => users.find(a => a == tweet.author_id), }, User: { fullName: user => `${user.first_name} ${user.last_name}`, }, };

{ getTweet(id: "1") { id body Author { fullName } } }

getTweet: (_, params) => tweets.find(t => t.id == params.id)

(null, { id: 1 }) { id: 1, body: 'Lorem Ipsum’, author_id: 10 }

1

{ getTweet(id: "1") { id body Author { fullName } } }

Tweet: { id: tweet => tweet.id, body: tweet => tweet.body, Author: tweet => users.find(a => a == tweet.author_id), }

{ id: 1, body: 'Lorem Ipsum’, author_id: 10 }12

{ getTweet(id: "1") { id body Author { fullName } } }

12 { id: ‘1’, body: 'Lorem Ipsum’, Author: {

id: 10, first_name: ‘John', last_name: 'Doe' } }

{ id: 1, body: 'Lorem Ipsum’, author_id: 10 }

{ getTweet(id: "1") { id body Author { fullName } } }

12

User: { fullName: user => `${user.first_name} ${user.last_name}`, }

3

{ id: 1, body: 'Lorem Ipsum’, author_id: 10 }

{ id: ‘1’, body: 'Lorem Ipsum’, Author: { id: 10, first_name: ‘John', last_name: 'Doe' } }

12

{ id: ‘1’, body: 'Lorem Ipsum’, Author: { fullName: ‘John Doe' } }

{ id: ‘1’, body: 'Lorem Ipsum’, Author: { id: 10, first_name: ‘John', last_name: 'Doe' } }

{ id: 1, body: 'Lorem Ipsum’, author_id: 10 }

3

{ getTweet(id: "1") { id body Author { fullName } } }

AVA I L A B L E I N Y O U R S E R V E R L A N G U A G E

• JavaScript

• PHP

• Ruby

• Python

• Go

• Java

• Scala

• C#

• Elixir

• Fortran

• BrainFuck

• etc…

const query = ` { getTweet(id: "1") { id body Author { name } } }`;

const headers = new Headers(); myHeaders.append('Content-Type', 'application/graphql');

fetch(‘/graphql’, { method: 'POST', body: query, headers }); .then(response => response.json) .then(response => response.data.getTweet) .then(tweet => ...);

import React from 'react'; import { gql, graphql } from 'react-apollo'; import LinearProgress from 'material-ui'; const Tweet = ({ data: { loading, tweet } }) => ( <div> {loading ? ( <LinearProgress /> ) : ( <div> <img src={tweet.author.avatar} className="avatar" /> <span className="author">{tweet.Author.name}</span> <div className="body">{tweet.body}</div> </div> )} </div> ); const query = gql`{ getTweet(id: "1") { id body Author { name } } }`; export default graphql(query)(App);

AVA I L A B L E I N Y O U R C L I E N T L A N G U A G E

• Vue.js

• React.js

• Angular.js

• Meteor.js

• Objective-C

• Swift

• Expo

• Java

• Kotlin

• Dart

• Fart

• etc…

T O U T E S T P R Ê T P O U R V O U S A C C U E I L L I R

• Simple

• Stable

• Sécurisé

• Performant

• Documenté

• Supporté

G R A P H Q L , A N G E O U D É M O N ?

PA R T I E 5 / 6

#diversité

POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 500 Internal Server Error POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 500 Internal Server Error POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK POST /graphql 200 OK

{ Tweets(limit: 100) { Author { Tweets(limit: 100) { Author { Tweets(limit: 100) { Author { Tweets(limit: 100) { Author { name } } } } } } } } }

Client Serverquery

Client Serverid

Dictionary Dictionary

query id id query

Pers

iste

d Q

uerie

s

G R A P H Q L , C ’ E S T P O U R Q U I ?

PA R T I E 6 / 6

Q U E L T Y P E D E D E V I C E U T I L I S E N T V O S C L I E N T S ?Q U E S T I O N # 1

D E S K T O P M O B I L E E T / O U D E S K T O P

L A P E R F O R M A N C E C Ô T É C L I E N T E S T- E L L E I M P O R TA N T E ?

Q U E S T I O N # 2

N O N

O U I

C O M B I E N D E R O U T E S A V O T R E A P I R E S T ? Q U E S T I O N # 3

5 A U P L U S

A U M O I S 6

Q U E L L E E S T L A D U R É E D E V I E D E V O T R E A P I ? Q U E S T I O N # 4

A U M O I N S U N A N Q U E L Q U E S

M O I S

Q U E L E S T L E N I V E A U D E C O M P L E X I T É D E V O T R E A P I ?

Q U E S T I O N # 5

S I M P L E

C O M P L E X E

S U R L A P L U S C O M P L E X E S D E S PA G E S D U C L I E N T, C O M B I E N D E P E R S I S T E N C E S S O N T A P P E L E E S ?

Q U E S T I O N # 6

U N

P L U S D E U N

AV E Z - V O U S D E S R È G L E S D E C A C H E C O M P L E X E S ? Q U E S T I O N # 7

N O N

O U I

C O M M E N T T R AVA I L L E N T V O S É Q U I P E S F R O N T E T B A C K ?

Q U E S T I O N # 8

B A C K L O G C O M M U N

S I L O

C O M B I E N D E D É V E L O P P E U R S ( F R O N T + B A C K ) T R AVA I L L E N T AV E C L’ A P I ?

Q U E S T I O N # 9

A U M O I N S C I N Q

U N À Q U AT R E

Q U E L E S T V O T R E T Y P E D E L A N G A G E P R É F É R É ?Q U E S T I O N # 1 0

F O R T E M E N T T Y P É

FA I B L E M E N T T Y P É

M E R C I ! D E S Q U E S T I O N S ?

F R A N Ç O I S Z A N I N O T T O @ f r a n c o i s z

top related