Successfully reported this slideshow.

GraphQL, l'avenir du REST ?

5

Share

YouTube videos are no longer supported on SlideShare

View original on YouTube

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
Loading in …3
×
1 of 102
1 of 102

GraphQL, l'avenir du REST ?

5

Share

Download to read offline

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.

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.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

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

×