Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL et Falcor, un autre regard sur les architectures REST

GraphQL et Falcor, un autre regard sur les architectures REST

Introduction à GraphQL et Falcor avec un résumé sur les cas d'utilisation.

Antoine Le Taxin

December 02, 2016
Tweet

More Decks by Antoine Le Taxin

Other Decks in Technology

Transcript

  1. @xebiconfr #xebiconfr GraphQL et Falcor, un nouveau regard sur les

    architectures REST Abdelhakim Bachar Antoine Le Taxin
  2. @xebiconfr #xebiconfr Besoin GraphQL for iOS par Simone Civetta GraphQL

    est une technologie dont vous avez entendu parler, peut-être, de vos collègues Front. Il s’agit d’une API middleware, similaire à un ESB, qui… Tags: Front, GraphQL, FalcorJS, React Commentaires Par Abdelhakim Bachar, Il y a 3 mois An awesome article Par Antoine Le Taxin, Il y a 3 mois Wow.. Thanks much for sharing.. 4 1a 5 articles, 30 commentaires
  3. @xebiconfr #xebiconfr RESTful (representational state transfer) ✔ Possibilité de cache

    ✔ Indépendance entre le modèle et la vue 5 1b { "id": 1, "title": "Lorem ipsum", "authorId": 1000 } { "id": 1000, "lastName": "Carver", "firstName": "Kerry" } ✘ Latence (grand nombre de requêtes ou réponse lourde) ✘ Over fetching [GET]/post/1 [GET]/user/1000
  4. @xebiconfr #xebiconfr Qu’est ce que GraphQL ? • Est une

    Spécification • Implémentée en plusieurs langages de programmation • Définit un langage permettant de requêter et récupérer de manière déclarative des données depuis un back-end 7 2a
  5. @xebiconfr #xebiconfr Trois points d’histoire • Créé par Facebook •

    Remplacer tous les services REST nécessaires aux applications mobile • En production depuis 2012 pour les applications iOS et Android de Facebook 8 2b
  6. @xebiconfr #xebiconfr A quoi ressemble une requête ? 10 2d

    // Résultat { "user": { "id": 123456 "name": "Abdelhakim Bachar" } } // Requête GraphQL query { user(id: 123456) { id name } }
  7. @xebiconfr #xebiconfr Hiérarchique 11 2f query { posts(id: 1000) {

    title content comments { content author { firstName } } } }
  8. @xebiconfr #xebiconfr const UserType = new GraphQLObjectType({ name: 'User', description:

    'Define a user resource', fields: () => ({ firstName: { type: GraphQLString, resolve: tag => tag.label }, posts: { type: new GraphQLList(PostType), resolve: tag => tag.getPosts() } }) }); Typage fort 13 2h
  9. @xebiconfr #xebiconfr const UserType = new GraphQLObjectType({ fields: () =>

    ({ fullName: { type: GraphQLString, deprecationReason: "You don't need it", resolve: user => `${user.firstName} ${user.lastName}` } }) }); Rétrocompatibilité 14 2i
  10. @xebiconfr #xebiconfr Introspectif 15 2j { __type(name: "User") { name

    kind } } { "data": { "__type": { "name": "User", "kind": "OBJECT" } } }
  11. @xebiconfr #xebiconfr Que des requêtes ? Non, pas seulement les

    requêtes, mais aussi la création, la mis à jour et la suppression grâce au Mutation 18 2m mutation { createUser( firstName: "Abdelhakim", lastName: "Bachar" ) { id created_at } }
  12. @xebiconfr #xebiconfr Comment requêter un serveur GraphQL ? POST curl

    -XPOST -d 'query{posts{title}}' http://localhost:3000/graphql GET curl http://localhost:3000/graphql?query={posts{title}} 19 2n
  13. @xebiconfr #xebiconfr const queryType = new GraphQLObjectType({ name: 'Query', description:

    'Root query entry point', fields: () => ({ users: UserQuery, posts: PostQuery // ... }) }); GraphQL Query 22 2q query { users(id: 123456) { id firstName } }
  14. @xebiconfr #xebiconfr const UserQuery = { type: new GraphQLList(UserType), args:

    { id: { type: GraphQLInt }, firstName: { type: GraphQLString } // ... }, resolve: (root, args) => User.findAll({where: args}) }; UserQuery 23 2s
  15. @xebiconfr #xebiconfr const UserType = GraphQLObjectType({ name: 'User', fields: ()

    => ({ id: { type: GraphQLInt, resolve: u => u.id }, firstName: { type: GraphQLString }, posts: { type: new GraphQLList(PostType), resolve: u => u.getPosts() } }) }); Type User 24 2t
  16. @xebiconfr #xebiconfr const mutationType = new GraphQLObjectType({ name: "Mutation", description:

    "Root mutation entry point", fields: () => ({ createUser: { type: UserType, args: { firstName: {type: new GraphQLNonNull(GraphQLString)} }, resolve: (source, args) => User.create(Object.assign({}, args)) } }) }); GraphQL Mutation 25 2r
  17. @xebiconfr #xebiconfr { posts(name: 12549) { id title content author

    { id firstName lastName } comments { content author { id firstName lastName count_comments count_posts } } } } La requête pour notre blog 26 2u GraphQL for iOS par Simone Civetta GraphQL est une technologie dont vous avez entendu parler, peut-être, de vos collègues Front. Il s’agit d’une API middleware, similaire à un ESB, qui… Tags: Front, GraphQL, FalcorJS, React Commentaires Par Abdelhakim Bachar, Il y a 3 mois An awesome article Par Antoine Le Taxin, Il y a 3 mois Wow.. Thanks much for sharing.. 5 articles, 30 commentaires
  18. @xebiconfr #xebiconfr • Est un librairie Javascript open source •

    Propose une manière impérative de décrire et d’accéder aux données • Embarque un système de cache et d’optimisation de requêtes Qu’est ce que Falcor ? 28 3a
  19. @xebiconfr #xebiconfr • Créé par Netflix • Répond aux besoins

    de performance, d’éclatement de leur sources de données et diversité des supports • En production pour leur applications TV, mobile et desktop et open source depuis 2015 Trois points d’histoire 29 3b
  20. @xebiconfr #xebiconfr Avoir un outil centré sur la performance et

    le cloud, spécialement adapté aux architectures microservices. Objectif 30 3c
  21. @xebiconfr #xebiconfr A quoi ressemble une requête ? 31 3d

    // Résultat { "user": { "name": "Abdelhakim B." } } // Requête falcor model .get('users[0].name') .then( // )
  22. @xebiconfr #xebiconfr • Langage de query de Falcor • Exprime

    un chemin au travers d’un objet JSON • Il accepte deux syntaxes : ◦ Syntaxe Path String ◦ Array de clés 'posts[1].title' ['posts', 1, 'title'] 'posts[1..2]['title','content']' ['posts', {from: 1, to: 2}, ['title','content']] Paths 33 3f
  23. @xebiconfr #xebiconfr • On accède aux données au travers d’un

    graph JSON unique (quelque soit le nombre de sources) // frontend var model = new falcor.Model({ source: new falcor.HttpDataSource('api/model.json') }) // backend app.use('/api/model.json', falcorExpress.dataSourceRoute((req, res) => { return new Router([ (...) ]) } ) Model 34 3g
  24. @xebiconfr #xebiconfr Le Modèle optimise les requêtes concurrentes model .get(

    'posts[0].title', 'posts[1].title', 'posts[0].content', 'posts[1].content, ) .then(/.../) // Path envoyé au backend sous form de “query string” paths: [["posts",{"from":0,"to":1},["title", “content”]]] Model 36 3i
  25. @xebiconfr #xebiconfr Le Modèle optimise les requêtes sortantes grâce au

    cache model .get('posts[0..1].title').then(/.../) // Path envoyé au backend sous form de “query string” paths: [["posts",{"from":0,"to":1},"title"]] model .get('posts[0..1][“title”,”content”]').then(/.../) // Path envoyé au backend est optimisé pour ne chercher que la donnée manquante paths: [["posts",{"from":0,"to":1},"content"]] Model 37 3j
  26. @xebiconfr #xebiconfr Pour permettre au JSON de passer d’arbre à

    graph. Types primitifs supplémentaires : • Reference (ref) : lien symbolique • Atom (atom) : valeur json (object / array) • Error (error) : erreur (surtout utilisé côté routeur) JSON Graph 38 3k
  27. @xebiconfr #xebiconfr { postsByIds: { 1000: { title: "Aliquip voluptate

    ", content: "Ex cupidatat ", author_id: falcor.Model.ref('usersByIds[1000]') }, 1001: {...} }, posts: [ { $type: 'ref', value:['postsByIds', 1000] }, { $type: 'ref', value:['postsByIds', 1001] } ] }}) JSON Graph : ref 39 3l
  28. @xebiconfr #xebiconfr Data Sources 40 3m Une interface qui permet

    d’exposer un JSON Graph Opérations disponibles pour Route ou Model : • get : lire • set : modifier • call : appeler une fonction du graph (non idempotent)
  29. @xebiconfr #xebiconfr Router • Pattern matching sur la structure du

    graph Json. • Trois types spécifiques : ◦ {integers} / {range} / {keys} • pathSet comprend les arguments du path sous forme d’array // front model.get('posts[0].title') // route route: "posts[{integers:postId}]['title', 'content']", get: (pathSet) => { return someAsyncService.getData(pathSet) //… pathSet[0] = posts / pathSet[1] = 0 / pathSet[2] = title // } 41 3n
  30. @xebiconfr #xebiconfr model.get( 'postsById[12549]["title", "content", "tags", "author"]' ) model.get(` authorsById[${data.author.id}]["firstName",

    "lastName"] `) model.get(` commentsById[${data.comments.from}..${data.comments.to}] ["content", "author"] `) model.get(` authorsById[${data.author.from}..${data.author.to}] ["firstName", "lastName", "count_comments", "count_post"] `) La requête pour notre blog 42 3o GraphQL for iOS par Simone Civetta GraphQL est une technologie dont vous avez entendu parler, peut-être, de vos collègues Front. Il s’agit d’une API middleware, similaire à un ESB, qui… Tags: Front, GraphQL, FalcorJS, React Commentaires Par Abdelhakim Bachar, Il y a 3 mois An awesome article Par Antoine Le Taxin, Il y a 3 mois Wow.. Thanks much for sharing.. 5 articles, 30 commentaires
  31. @xebiconfr #xebiconfr Avantages / inconvénients de GraphQL ✔ Déclaratif (requête,

    type) ✔ Documentation vivante ✔ Exploration facile des données ✔ Une seule requête suffit ✔ Contrôle total sur la granularité des informations ✘ Ne supporte ni les opérateurs, ni les fonctions d'agrégation ✘ Pas de gestion automatique du cache 44 4a
  32. @xebiconfr #xebiconfr Avantages / inconvénients de Falcor ✔ Gestion automatique

    du cache ✔ Optimisation à la volée des requêtes ✔ Contrôle total sur la granularité des informations ✔ Optimisé pour la gestion de sources de données multiples ✔ Le code front et back utilisent la même librairie ✘ Impératif (pas de type) ✘ Ne supporte ni les opérateurs, ni les fonctions d'agrégation ? Implémentation du backend est laissé à la charge du développeur 45 4b
  33. @xebiconfr #xebiconfr Cas d’utilisation Prendre l’une des deux solutions si

    : - Beaucoup de lecture, peu d’écriture - Le réseau et la latence est la principale préoccupation (Mobile) S’orienter vers GraphQL si : - Vous voulez une validation du modèle et une documentation - Vous voulez utiliser autre langage que Javascript S’orienter vers Falcor si : - Vos données sont réparties à différents endroits - Vous voulez un cache géré automatiquement et optimisé 46 4c