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

GraphQL et Falcor, un autre regard sur les arch...

GraphQL et Falcor, un autre regard sur les architectures REST

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

Avatar for Antoine Le Taxin

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