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 L
g 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 /notification...
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
• Ev...
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.name

FROM tweets t LEFT JOIN author a 

ON tweet.aut...
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
• ...
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 }
}
HT...
POST / HTTP 1.1
Host: http://graphql.acme.com/
Content-Type: application/graphql
{
getTweets(limit: 10, sortField: "date",...
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"getTweets": [
{
"id": "752",
"body": "The guy next to me is li...
POST / HTTP 1.1
Host: http://graphql.acme.com/
Content-Type: application/graphql
{
getTweets(limit: 10, sortField: "date",...
POST / HTTP 1.1
Host: http://graphql.acme.com/
Content-Type: application/graphql
{
getTweets(limit: 10, sortField: "date",...
{
"data": {
"getTweets": [
{
"id": "752",
"body": "The guy next to me is listening...",
"date": "2017-07-15T13:17:42.772Z"...
POST / HTTP 1.1
Host: http://graphql.acme.com/
Content-Type: application/graphql
{
getTweets(limit: 10, sortField: "date",...
# entry points
type Query {
getTweet(id: ID!): Tweet
getTweets(limit: Int, sortField: String, sortOrder: String): [Tweet]
...
# entry points
type Query {
getTweet(id: ID!): Tweet
getTweets(limit: Int, sortField: String, sortOrder: String): [Tweet]
...
POST / HTTP 1.1
Host: http://graphql.acme.com/
Content-Type: application/graphql
{
getTweets(limit: 10, sortField: "date",...
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
}
ty...
const resolvers = {
Query: {
getTweet: (_, params) => tweets.find(t => t.id == params.id),
getTweets: (_, params) => tweet...
{
getTweet(id: "1") {
id
body
Author {
fullName
}
}
}
getTweet: (_, params) => tweets.find(t => t.id == params.id)
(null, ...
{
getTweet(id: "1") {
id
body
Author {
fullName
}
}
}
Tweet: {
id: tweet => tweet.id,
body: tweet => tweet.body,
Author: t...
{
getTweet(id: "1") {
id
body
Author {
fullName
}
}
}
1
2 { id: ‘1’, body: 'Lorem Ipsum’, Author: {
id: 10,
first_name: ‘J...
{
getTweet(id: "1") {
id
body
Author {
fullName
}
}
}
1
2
User: {
fullName: user => `${user.first_name} ${user.last_name}`...
1
2
{ id: ‘1’, body: 'Lorem Ipsum’, Author: {

fullName: ‘John Doe'

}
}
{ id: ‘1’, body: 'Lorem Ipsum’, Author: {
id: 10,...
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#
• Elix...
const query = `
{
getTweet(id: "1") {
id
body
Author {
name
}
}
}`;
const headers = new Headers();
myHeaders.append('Conte...
import React from 'react';
import { gql, graphql } from 'react-apollo';
import LinearProgress from 'material-ui';
const Tw...
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...
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...
{
Tweets(limit: 100) {
Author {
Tweets(limit: 100) {
Author {
Tweets(limit: 100) {
Author {
Tweets(limit: 100) {
Author {
...
Client Server
query
Client Server
id
Dictionary Dictionary
query id id query
PersistedQueries
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 ...
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 ...
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 ...
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 ...
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 ...
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 # ...
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 RT E M E N T 

T Y P É
FA I B ...
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
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
Prochain SlideShare
Chargement dans…5
×

GraphQL, l'avenir du REST ?

608 vues

Publié le

REST est devenu un standard pour les APIs web. Mais malgré sa popularité, il est plein de défauts. Son successeur existe et il vient de Facebook. Venez découvrir en détail le principe, la mise en oeuvre et l’écosystème de GraphQL.

Publié dans : Internet
  • Soyez le premier à commenter

GraphQL, l'avenir du REST ?

  1. 1. 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
  2. 2. G R A P H Q L g r a f k ɥ ɛ l G R A S K A F K A E C U E L L E
  3. 3. L E P R O B L È M E PA R T I E 1 / 6
  4. 4. R E S T
  5. 5. 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
  6. 6. B R E A K I N G C H A N G E
  7. 7. 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
  8. 8. L E S A U T R E S C A N D I D AT S PA R T I E 2 / 6
  9. 9. R E S T + + GET /tweets?include=author&fields=[id,date,body]
  10. 10. S Q L O V E R H T T P GET /data?query=
 SELECT t.id, t.date,t.body,a.name
 FROM tweets t LEFT JOIN author a 
 ON tweet.author_id = author.id
 LIMIT 10
  11. 11. P R O T O C O L B U F F E R S
  12. 12. FA L C O R
  13. 13. 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
  14. 14. D É C O U V R E Z G R A P H Q L PA R T I E 3 / 6
  15. 15. 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. } RequêteRéponse REST GraphQL
  16. 16. 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 } } Requête
  17. 17. 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éponse
  18. 18. 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 } } Requête
  19. 19. 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 } } Requête
  20. 20. { "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éponse
  21. 21. 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 } } Requête
  22. 22. # 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
  23. 23. # 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
  24. 24. 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 } } } Requête
  25. 25. 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
  26. 26. 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
  27. 27. type Query { getTweet(id: ID!): Tweet getTweets(limit: Int): [Tweet] } type Tweet { id: ID! body: String Author: User } type User { fullName: String }
  28. 28. 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}`, }, };
  29. 29. { 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
  30. 30. { 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 }1 2
  31. 31. { getTweet(id: "1") { id body Author { fullName } } } 1 2 { id: ‘1’, body: 'Lorem Ipsum’, Author: { id: 10, first_name: ‘John', last_name: 'Doe' } } { id: 1, body: 'Lorem Ipsum’, author_id: 10 }
  32. 32. { getTweet(id: "1") { id body Author { fullName } } } 1 2 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' } }
  33. 33. 1 2 { 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 } } }
  34. 34. 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…
  35. 35. 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 => ...);
  36. 36. 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);
  37. 37. 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…
  38. 38. 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é
  39. 39. G R A P H Q L , A N G E O U D É M O N ? PA R T I E 5 / 6
  40. 40. #diversité
  41. 41. 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
  42. 42. { Tweets(limit: 100) { Author { Tweets(limit: 100) { Author { Tweets(limit: 100) { Author { Tweets(limit: 100) { Author { name } } } } } } } } }
  43. 43. Client Server query Client Server id Dictionary Dictionary query id id query PersistedQueries
  44. 44. 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
  45. 45. 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
  46. 46. 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
  47. 47. 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
  48. 48. 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
  49. 49. 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
  50. 50. 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
  51. 51. 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
  52. 52. 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
  53. 53. 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
  54. 54. 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 RT E M E N T 
 T Y P É FA I B L E M E N T 
 T Y P É
  55. 55. 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

×