<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[We Craft Apps - Medium]]></title>
        <description><![CDATA[Web, mobile and digital transformation experts from Nantes - Medium]]></description>
        <link>https://medium.com/wecraftapps?source=rss----fa18b7351356---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>We Craft Apps - Medium</title>
            <link>https://medium.com/wecraftapps?source=rss----fa18b7351356---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 19:24:32 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/wecraftapps" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Startups, ne laissez pas votre tech être un problème.]]></title>
            <link>https://medium.com/wecraftapps/startups-ne-laissez-pas-votre-tech-%C3%AAtre-un-probl%C3%A8me-b8769376e5ae?source=rss----fa18b7351356---4</link>
            <guid isPermaLink="false">https://medium.com/p/b8769376e5ae</guid>
            <category><![CDATA[web]]></category>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[tech]]></category>
            <dc:creator><![CDATA[Renaud Lataguerra]]></dc:creator>
            <pubDate>Mon, 15 Feb 2021 15:06:10 GMT</pubDate>
            <atom:updated>2021-02-15T18:24:51.997Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hSc4mXb5FvNTiuAbcHtP-g.jpeg" /></figure><blockquote><strong>Initialement posté sur : </strong><a href="https://www.wecraftapps.com/blog-startups-ne-laissez-pas-votre-tech-etre-un-probleme"><strong>https://www.wecraftapps.com/blog-startups-ne-laissez-pas-votre-tech-etre-un-probleme</strong></a></blockquote><p>Chez We Craft Apps nous sommes un <a href="https://www.wecraftapps.com/studio">Product Studio</a>, nous développons pour nos clients des solutions Web et mobiles.</p><p>Quel que soit le stade du projet: POC, MVP ou la réalisation d’un produit plus mature, notre mission c’est d’aider nos clients à réussir leurs projets numériques.</p><p>En 8 années d’accompagnement, on a croisé pas mal de monde, des grands groupes étonnamment agiles, des startups qui n’en sont pas, des industriels, des organismes publics, des projets réussis et d’autres qui n’ont pas rencontré leur public.</p><p>S’il est difficile de se prononcer sur le core-business de chacun, nous avons un avis sur l’approche technique à avoir qui constitue, selon nous, l’une de nos valeurs ajoutées.</p><h4>Certitudes</h4><blockquote>It ain’t what you don’t know that gets you into trouble. It’s what you know for sure that just ain’t so. — Mark Twain</blockquote><p>Nous rencontrons une multitude de profils de porteurs de projets et la <strong>plupart connaissent finalement assez mal la technique</strong>. Ce constat n’est aucunement une critique, sinon nous n’aurions pas lieu d’exister, pour autant, il arrive quelquefois, que des porteurs de projets viennent nous rencontrer avec des idées un peu trop précises sur les technos et architectures à mettre en place. Qui pourrait les blâmer de s’intéresser, de faire des recherches ou encore de faire confiance à un ami ? Seul souci, ils finissent par construire des certitudes dans un domaine qu’ils ne connaissent pas.</p><p>Et ça, c’est le début d’un problème.</p><p>Il m’arrive notamment de croiser certains points de préoccupation de la part des créateurs de startups, que je trouve très en décalage avec la maturité de leur produit, ou avec ses nécessités technologiques actuelles.</p><p>Par exemple : une architecture en micro services, la performance, le NoSQL (cette liste est en réalité beaucoup plus longue et peut contenir toutes technos/archi à la mode sur le moment 🥳)</p><p>En général ma réponse tient en quelques mots : “vous n’en avez pas besoin, vous essayez d’anticiper des problèmes qui n’existent pas encore”.</p><p>Mais alors, pourquoi tant de certitudes ?</p><p>En résumé ça donne quelque chose comme : les géants (GAFAM, grosses scale-up, etc…) utilisent ces solutions, ils sont successful, alors, pour être successful, moi aussi j’utilise la même sauce.</p><h4>Uber, Pinterest, Slack et Instagram</h4><p>Prenons le temps de regarder vraiment les choses avec quelques exemples en provenance d’Uber, Pinterest, Slack et Instagram. Avouez que le lineup est pas mal.</p><p><strong>Uber</strong></p><p>Chez Uber il y a eu une transition d’architecture en 2015, voilà ce que raconte Gergely Orosz de chez Uber :</p><blockquote><em>[…] Uber went from monolith to SOA in 2015. This SOA followed a microservice-based architecture. And different engineers have been sharing what they’ve learned along the way: the steps it usually takes to build a microservice, addressing testing problems with a multi-tenancy approach or how and why teams use distributed tracing. […] All of these can serve as inspiration: but the end of the day, you need to make decisions in your environment that you think will work best. </em><strong><em>Anyone copying the likes of Google, Uber, Shopify, Stack Overflow or others when they’re not even similar in setup will be disappointed</em></strong><em>.</em></blockquote><p><em>☝️ N’essayez pas de résoudre des problématiques que vous n’avez pas, une architecture en micro-service soulève énormément de nouvelles problématiques par rapport à un monolithe. Voyez ça comme des problèmes en moins si ce n’est pas nécessaire pour vous.</em></p><p><strong>Pinterest</strong></p><p>En 2011, les serveurs étaient en feu chez Pinterest, voila ce que raconte Marty Weiner :</p><blockquote><em>In 2011, we hit traction. By some estimates, we were growing faster than any other previous startup. Around September 2011, every piece of our infrastructure was over capacity. We had several NoSQL technologies, all of which eventually broke catastrophically. [..] We intentionally ran away from auto-scaling newer technology like MongoDB, Cassandra and Membase, because their maturity was simply not far enough along (and they were crashing in spectacular ways on us!). </em><strong><em>Aside: I still recommend startups avoid the fancy new stuff […] Trust me. I have the scars to prove it</em></strong><em>.</em></blockquote><p><em>☝️ Il faut replacer ce témoignage dans le temps, et comprendre que la problématique n’est pas fondamentalement de travailler avec du NoSQL ou pas, mais davantage d’avoir un recul par rapport à l’émergence de nouvelles technos : faire attention aux technologies un peu trop hypes, un peu trop miraculeuses, faire attention au marketing autour d’une techno/produit.</em></p><p><strong>Slack</strong></p><p>Fin 2016, Keith Adams alors chief architect chez Slack, partage des détails sur son architecture :</p><blockquote>Slack consists of a sharded LAMP stack; webservers, memcache, and a fleet of mysql instances […] <strong>Users care that persistence works and they don’t lose data, not what the storage system is.</strong></blockquote><p><em>☝️ Cette phrase de Keith Adams témoigne de la simplicité avec laquelle il est parfois possible d’aborder les choses. Également, vos utilisateurs finaux ne sont pas intéressés par comment marche techniquement votre système, ils veulent juste que le service pour lequel ils payent marche.</em></p><p><strong>Instagram</strong></p><p>Mike Krieger, co-fondateur d’Instagram raconte dans un article de 2013 :</p><blockquote>As we’ve scaled Instagram to an ever-growing number of active users, <strong>Postgres has continued to be our solid foundation and the canonical data storage for most of the data created by our users</strong>. […]</blockquote><p><em>☝️ Cette phrase est issue d’un article particulièrement intéressant sur l’usage de PostgreSQL chez instagram. Un choix simple, non hype, qui avec un peu d’imagination et un usage un peu avancé permet d’aller plus loin que ce qu’imagine, malheureusement, la plupart des utilisateurs de solutions alternatives.</em></p><h4>Ne pas perdre son temps et son argent dans des sur-complexités inutiles</h4><p>🙌 Ces acteurs du numérique méritent d’être regardés mais uniquement avec un recul suffisant pour mettre en perspective à travers le temps leurs évolutions. Il faut davantage regarder le point de départ que celui d’arrivée.</p><p>Pour insister sur cette mise en perspective, quand Gergely Orosz parle d’Uber en 2015, le NYTimes titre : Uber Valuation Put at $62.5 Billion et c’était aussi l’année des 1 billion rides. Plus vraiment le MVP d’une startup.</p><p>Êtes-vous déjà à cette étape ?</p><p>D’ailleurs, comprenez que si vous souhaitez tout penser par le prisme de l’hyper scalabilité, day 1, vous allez principalement réussir à faire deux choses : ralentir vos développements et multiplier le coût de votre solution par au moins 10.</p><p>Résultat des courses, votre time to market est naze et de toutes les manières vous n’avez pas cet argent.</p><h4>Un maximum de valeur ajoutée avec peu de features</h4><p>Le meilleur conseil que je puisse donner en général aux startups que j’accompagne c’est de délivrer un maximum de valeur ajoutée avec peu de features, mais des features différenciantes.</p><p>Pour ce faire, il ne faut pas perdre son temps et son argent dans des sur-complexités inutiles côté stack, infra ou architecture.</p><p>Plus votre stack technique est “boring”, moins vous aurez de chances de vous crasher à cause de celui-ci.</p><p>Les sujets concernés sont véritablement nombreux. Pensez-vous qu’une startup qui peine à trouver des clients doit ériger Kubernetes en première prio ? Malheureusement certaines pensent que oui et je suis confronté régulièrement à ce genre de discussions (nous avons d’ailleurs la chance en France d’avoir d’excellents acteurs du PaaS 🚀).</p><p>Au quotidien, j’essaie d’insuffler cette vision pragmatique à la fois dans l’aspect pédagogique auprès du client mais aussi du côté technique auprès de mon équipe.</p><ul><li>une architecture suffisamment simple pour pouvoir réfléchir rétrospectivement et évoluer vers plus de complexité quand c’est nécessaire,</li><li>des bonnes pratiques et du code suffisamment propre pour que le projet soit reprenable et évolutif,</li><li>une utilisation de solutions SaaS quand il n’y pas besoin de souveraineté,</li><li>une utilisation systématique de PaaS.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b8769376e5ae" width="1" height="1" alt=""><hr><p><a href="https://medium.com/wecraftapps/startups-ne-laissez-pas-votre-tech-%C3%AAtre-un-probl%C3%A8me-b8769376e5ae">Startups, ne laissez pas votre tech être un problème.</a> was originally published in <a href="https://medium.com/wecraftapps">We Craft Apps</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Une API GraphQL de zéro en NodeJS]]></title>
            <link>https://medium.com/wecraftapps/une-api-graphql-de-z%C3%A9ro-en-nodejs-8396dc652fb4?source=rss----fa18b7351356---4</link>
            <guid isPermaLink="false">https://medium.com/p/8396dc652fb4</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[koa]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[graphql]]></category>
            <category><![CDATA[api]]></category>
            <dc:creator><![CDATA[Frédéric]]></dc:creator>
            <pubDate>Thu, 22 Mar 2018 15:49:25 GMT</pubDate>
            <atom:updated>2018-03-23T00:11:08.137Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rvVXT9kfveC8FUZLhOMsBw.jpeg" /></figure><p>GraphQL est un langage de requêtage d’API développé par Facebook. Tout comme REST, GraphQL est une méthode d’implémentation d’API répondant à des standards. De nombreuses personnes en parlent et publient des exemples et je ne vais pas déroger à la règle. Cet article a pour but d’introduire l’approche GraphQL et de vous accompagner pas à pas, à travers l’implémentation complète d’une API en GraphQL, en utilisant Koa, Knex et Postgres.</p><h4>GraphQL vs REST</h4><p>Il existe quatre grands points différenciant les deux types d’API.</p><p><strong>Nombre de routes</strong></p><p>Dans une API REST, chaque route est prévue pour renvoyer un certain type de données. Il est usuel de définir des routes GET, POST, UPDATE, DELETE pour chaque table présente dans la base de données.</p><p>Dans GraphQL, une seule route est nécessaire. Toutes les requêtes sont envoyées à la même route et cette dernière est capable de traiter toutes les demandes. Bon j’exagère, il faut deux routes et non pas une. Une en GET et une en POST.</p><p><strong>Over-fetching / Under-fetching</strong></p><p>Dans une implémentation REST, chaque route renvoie une certaine structure de données qui est fixe. Même si le client n’a pas besoin de connaitre l’âge d’un utilisateur, l’API le renverra pour chaque profil utilisateur, car c’est ce pour quoi elle a été programmée. Ici, l’API a le pouvoir.</p><p>Dans le cas de GraphQL, la route ne renvoie QUE les données que le client demande. Si le client n’a pas l’utilité de connaitre l’âge d’un utilisateur alors l’API ne renverra pas l’âge pour chaque utilisateur. Dans ce cas-ci l’API adapte sa réponse en fonction de la demande du client. Ici, le client a le pouvoir.</p><p><strong>Syntaxe simple</strong></p><p>Un élément particulièrement intéressant de l’approche GraphQL est la syntaxe des requêtes.</p><blockquote>Ask for what you need, get exactly that</blockquote><p>La requête envoyée correspond au format de la réponse attendue. Ce qui donne des requêtes simples, logiques et claires. Prenons un exemple:</p><pre>query {<br> authors {<br>  author_id<br>  first_name<br>  last_name<br> }<br>}</pre><p>Mais que va donc nous renvoyer cette requête GraphQL ? Vous l’avez ?</p><p>Bien évidemment, elle nous permet de récupérer la liste des auteurs présents dans la base de données avec un détail pour chaque auteur. Non seulement ça, nous pouvons aussi indiquer quels champs nous souhaitons récupérer pour chaque auteur.</p><p>Encore un exemple:</p><pre>query {<br> authors {<br>  author_id<br> }<br>}</pre><p>Cette requête nous permet de récupérer la réponse suivante:</p><pre>“data”: {<br> “authors”: [<br>  {<br>   “author_id”: “e7691735–6e7c-495e-a422-a001824893e6”<br>  },<br>  {<br>   “author_id”: “7295d773–5eed-44cf-8b65-dc5d65995cf1”<br>  },<br>  {<br>   “author_id”: “c470d114–4f74–4250-ad40-d510b2a1a5f4”<br>  },<br>  {<br>   “author_id”: “830945ce-f48d-4c8d-a483–311511d480b0”<br>  }<br> ]<br>}</pre><p>Et oui, uniquement les ID des auteurs. Magique non ?</p><p><strong>Nombre de requêtes</strong></p><p>Le dernier point que je souhaite mettre en avant est le nombre de requêtes nécessaire pour obtenir les données souhaitées.</p><p>Prenons l’exemple de films, sur lesquels il est possible de laisser des commentaires. Chaque commentaire est lié à un auteur. Vous voyez le truc venir ?</p><p>Imaginons que vous souhaitiez afficher les détails d’un film sur une page. Vous récupérez alors votre objet film avec toutes ses données, nom, date de réalisation, budget, nom des acteurs… Maintenant, vous souhaitez afficher l’espace commentaire. Super, votre objet film dispose d’une liste de commentaires, c’est parfait !</p><p>Par contre, ce ne sont pas des objets commentaires, ce ne sont que les ID des commentaires. Là vous voyez le truc venir. Vous devez alors parcourir la liste des commentaires et récupérer chaque objet commentaire avec une nouvelle requête à l’API.</p><p>Mais ce n’est pas fini, n’oubliez pas les auteurs ! Pour chaque commentaire récupéré, vous devez alors effectuer une nouvelle requête pour retrouver l’auteur du commentaire et ses données. Bon pas de parcours de liste cette fois, un auteur pour un commentaire.</p><p>Vous voyez qu’avec une API REST, il est nécessaire d’effectuer de nombreuses requêtes différentes en fonction des besoins du client. Les routes sont fixes et renverront toujours le même format de données. Le standard veut que vous créiez des routes pour chaque type de données, ici des routes pour les films, pour les commentaires et pour les auteurs. Ce qui vous oblige à multiplier les appels lorsque vous voulez récupérer vos données.</p><p>Dans le cas de GraphQL, et en reprenant le même contexte de page détaillant un film, une seule requête est nécessaire.</p><pre>query {<br> movies(movie_id: &quot;f28d887c-1768-407c-8cc4-3c6f43255cb1&quot;) {<br>  movie_id<br>  name<br>  genre<br>  rating<br>  explicit<br>  comments {<br>   comment_id<br>   content<br>   author {<br>    author_id<br>    first_name<br>    last_name<br>   }<br>  }<br> }<br>}</pre><p>Boum.</p><p>Il suffit d’indiquer que vous souhaitez récupérer les données d’un film, et lorsque vient le moment de récupérer les commentaires, champ comments, vous indiquez alors les champs que vous souhaitez retrouver pour chaque commentaire. De la même manière le champ author est un objet décrivant les champs que vous souhaitez récupérer à propos des auteurs.</p><h4>Spécificités de GraphQL</h4><p>Tout cela est bien joli mais pour que ça fonctionne, GraphQL comporte plusieurs spécificités.</p><p><strong>Schemas</strong></p><p>Tout d’abord, GraphQL se base sur des schémas pour connaitre le format des données qu’il va servir. Ces schémas sont décrits dans un simple fichier texte.</p><pre>type Author {<br> author_id: ID<br> first_name: String<br> last_name: String<br>}</pre><p>Cet exemple de schéma décrit un objet author qui contient trois champs: <em>ID</em>, <em>prénom</em>, <em>nom</em>.</p><p>Mais ce n’est pas tout, ce fichier texte contient aussi les prototypes des fonctions permettant d’interagir avec l’API (comme des routes en REST).</p><pre>type Query {<br> authors(author_id: ID, first_name: String, last_name: String): [Author]<br>}</pre><p>Les prototypes de type <strong>Query</strong> correspondent à des fonctions de récupération simple d’information (comme des GET). Ici, nous indiquons que l’API peut renvoyer une liste d’auteurs et qu’elle accepte des paramètres de recherche, <em>ID</em>, <em>nom</em>, <em>prénom</em>.</p><pre>type Mutation {<br> addAuthor(author_id: ID, first_name: String, last_name: String): Author<br> updateAuthor(author_id: ID!, first_name: String, last_name: String): Author<br> deleteAuthor(author_id: ID!): Author<br>}</pre><p>Les prototypes de type <strong>Mutation</strong> correspondent aux fonctions d’altération de la base de données (comme des POST, UPDATE ou DELETE). Ici, nous indiquons que l’API est capable d’ajouter un auteur, de mettre à jour les informations d’un auteur ou bien de supprimer une entrée author.</p><p><strong>Middleware</strong></p><p>Les schémas précédents doivent alors être transformés en une représentation javascript pour être envoyée à la fonction makeExecutableSchema qui associe les schémas avec les <strong>resolvers</strong>.</p><p>Les <strong>resolvers</strong> sont l’implémentation des fonctions de type <strong>Query</strong> et <strong>Mutation</strong> dont les prototypes ont été définis dans le fichier des schémas. Leur but est de retrouver l’information demandée et de la renvoyer au client.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4f4f566ed4dcc25ff0781cc5f64b0525/href">https://medium.com/media/4f4f566ed4dcc25ff0781cc5f64b0525/href</a></iframe><p><strong>Attention ! Point important à noter !</strong></p><p>Les objets d’une base de données font souvent référence à d’autres tables, donnant ainsi des objets à plusieurs niveaux. Comme exemple, nous pouvons prendre la liste des commentaires d’un film. Un objet film disposera d’une liste d’ID faisant référence à des commentaires. Nous avons donc notre objet film</p><pre>type Movie {<br> movie_id: ID<br> name: String<br> genre: String<br> rating: Int<br> explicit: Boolean<br> comments: [Comment]<br>}</pre><p>GraphQL rend la récupération des commentaires très simple. En effet, le schéma ci-dessus indique qu’un film contient un champ comments qui est une liste d’objet Comment qui est aussi définit dans les schémas. Mais les schémas ne décrivent pas la manière de récupérer les commentaires à partir d’un film. Cette logique doit être décrite dans le fichier <strong>Middleware</strong>.</p><pre>Movie: {<br> comments: async (movie) =&gt; {<br>  const arr = await Promise.all(movie.comments.map(async (comment) =&gt; {<br>   const coms = await queries.getComments({ comment_id: comment });<br>   return coms[0];<br>  }));<br>  return arr;<br> },<br>},</pre><p>Ici, nous déclarons une entrée Movie faisant référence à un objet film, puis une entrée comments indiquant la logique de récupération des données du champ comments .</p><h4>Implémentation</h4><p>La théorie c’est bien mais la pratique c’est bien aussi. Pour une démonstration, j’ai dû implémenter une API GraphQL. Bon je ne vous cache pas que je n’ai pas réussi du premier coup, ni du second d’ailleurs… J’ai eu du mal à trouver les bonnes infos et les bons exemples. Je ne veux pas qu’il vous arrive la même chose, c’est pourquoi je me propose de partager mon expérience dans l’implémentation d’une API GraphQL en NodeJS avec Koa, Knex et Apollo GraphQL. Je souhaite vraiment partir de zéro point zéro car, personnellement, je manque d’expérience et de connaissances et je suis bien content lorsque je tombe sur un tutoriel expliquant pas à pas l’implémentation.</p><p>Pour ajouter du sens à l’exemple, j’ai pris un contexte simple et réaliste. Votre système décrit des films qui ont un nom, un genre, une note, un indicateur si le contenu est explicite mais aussi une liste de commentaires. Ces commentaires ont un contenu et un auteur. Pour finir les auteurs sont décrits par leur nom et prénom.</p><p><strong>Initialisation du projet</strong></p><p>Commencez par créer un nouveau projet dans votre IDE préféré. Je vous l’avais dit on part de zéro.</p><p>La première étape consiste à initialiser le projet npm, pour cela effectuez la commande npm init</p><p>Un fichier package.json est alors créé.</p><p><strong>Mise en place des outils</strong></p><p>Pour ce tutoriel vous allez devoir installer plusieurs librairies:</p><ul><li>Koa</li></ul><p>npm install koa --save</p><ul><li>Utilitaires Koa</li></ul><p>npm install koa-bodyparser koa-helmet koa-router --save</p><ul><li>Knex</li></ul><p>npm install knex --save</p><ul><li>Knex CLI</li></ul><p>npm install knex@0.13.0 -g</p><ul><li>Postgres</li></ul><p>npm install pg --save</p><ul><li>GraphQL</li></ul><p>npm install graphql graphql-tools apollo-server-koa --save</p><p><strong>Création de la base de données</strong></p><p>Avant toute chose, il est nécessaire de disposer d’une base de données à utiliser pour pouvoir tester l’API. Pour cela, j’ai utilisé une application Mac nommée <a href="https://postgresapp.com/">Postgres App</a>.</p><p>Lancer cette application, démarrera un serveur mettant des bases de données Postgres à disposition. Vous pouvez créer une nouvelle base de données si vous le souhaitez, ou bien utiliser l’une de celles déjà présentes sur le serveur.</p><p>Pour créer une base de données, via l’application <a href="https://eggerapps.at/postico/">Postico</a> et plus précisément le <strong>SQL Query</strong>, exécutez la requête:</p><p>CREATE DATABASE koa_test</p><p><strong>Initialisation du projet</strong></p><p>Maintenant que toutes les dépendances et la base de données sont installées, vous allez pouvoir procéder à l’initialisation de knex. Outil permettant de construire les requêtes interrogeant la base de données Postgres.</p><p>La commande:</p><p>knex init</p><p>permet de créer un fichier knexfile.js</p><p>Vous allez directement modifier ce fichier pour obtenir:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ff325447a02c175dc877f7ed2578ca5c/href">https://medium.com/media/ff325447a02c175dc877f7ed2578ca5c/href</a></iframe><p>N’oubliez pas de remplacer <em>username</em>, <em>password</em>, <em>database</em> par les informations que vous avez renseignées à la création de la base de données.</p><p>Ce fichier permet de faire le lien entre la base de données Postgres et les requêtes construites par Knex. Nous trouvons aussi notamment les chemins vers les fichiers de <strong>migrations</strong> et de <strong>seeds</strong>, que nous verrons juste après.</p><p><strong>Construire la base de données</strong></p><p>Pour le moment vous disposez d’une base de données vide, sans tables ni informations. Knex va rentrer en jeu et vous permettre de créer tout ce dont vous avez besoin.</p><p>knex migrate:make authors</p><p>La commande migrate de Knex permet de créer un fichier javascript contenant les instructions pour créer une table dans la base de données. Vous allez remplacer le contenu du fichier créé par:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9ec3a28f37d18beedd2337d724629966/href">https://medium.com/media/9ec3a28f37d18beedd2337d724629966/href</a></iframe><p>De la même manière, vous allez créer les fichiers pour créer les tables des commentaires et des films.</p><p>knex migrate:make comments</p><p>Que vous allez remplir avec:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/24142c2abbe79b314535f74812b83a41/href">https://medium.com/media/24142c2abbe79b314535f74812b83a41/href</a></iframe><p>knex migrate:make movies</p><p>Que vous allez remplir avec:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/56e47a00b1f1a3bd1a9c57b73557998c/href">https://medium.com/media/56e47a00b1f1a3bd1a9c57b73557998c/href</a></iframe><p>Une fois, les trois fichiers créés, vous allez pouvoir créer ces tables dans la base de données Postgres, pour cela il va falloir <strong>jouer</strong> les migrations. Terme employé lors de l’exécution de requêtes sur une base de données. Lancez la commande suivante:</p><p>knex migrate:latest --env development</p><p>Via, Postico, vous devriez maintenant voir les tables <em>authors</em>, <em>comments</em>, <em>movies</em> dans votre base de données.</p><p><strong>Peupler la base de données</strong></p><p>À cette étape du tutoriel vous devriez avoir une base de données avec des tables vides. C’est parfait, il faut maintenant les remplir de données. Pour cela, vous allez utiliser knex et son système de seeds.</p><p>knex seed:make authors_seed</p><p>Cette commande permet de créer un fichier authors_seed.js contenant les instructions pour ajouter des données à votre table authors.</p><p>Remplacez le contenu du fichier par:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dbd32a89978bea798854d4cbb83db649/href">https://medium.com/media/dbd32a89978bea798854d4cbb83db649/href</a></iframe><p>De la même manière, vous allez remplir les tables comments et movies.</p><p>knex seed:make comments_seed</p><p>Et remplacer par:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/afecfa58159d0cb5491fe9f3edc6a9db/href">https://medium.com/media/afecfa58159d0cb5491fe9f3edc6a9db/href</a></iframe><p>Et pour finir:</p><p>knex seed:make movies_seed</p><p>A remplacer par:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8f5719b5b55206d8189efffe4428f975/href">https://medium.com/media/8f5719b5b55206d8189efffe4428f975/href</a></iframe><p>Tout comme pour les migrations, vous allez maintenant jouer les seed pour insérer ces données dans les tables.</p><p>knex seed:run --env development</p><p>Via, Postico, vous devriez maintenant voir les tables <em>authors</em>, <em>comments</em>, <em>movies</em> remplies.</p><p><strong>Partie GraphQL</strong></p><p>Nous rentrons désormais dans le vif du sujet et ce pourquoi vous avez cliqué sur cet article, la mise en place de l’approche GraphQL. GraphQL n’est pas un outil à part entière, c’est une méthode d’implémentation, tout comme REST. C’est pourquoi diverses librairies proposent une implémentation GraphQL en javascript. Dans le cadre de ce tutoriel j’ai utilisé la librairie apollo-server-koa qui permet de mettre en place les standards GraphQL dans une API NodeJS utilisant Koa.</p><p>Première étape. Créer le fichier contenant les schémas de notre système. Créez donc un fichier /src/server/db/graphql/schemas.graphql dont le contenu est:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ecedf8e3ba87d0c9ad83a39b0841f558/href">https://medium.com/media/ecedf8e3ba87d0c9ad83a39b0841f558/href</a></iframe><p>Vous pouvez voir dans ce fichier, que nous commençons par définir la structure de données, en décrivant les objets contenus dans la base de données. Ensuite, nous décrivons les fonctions <strong>Query</strong> correspondantes aux GET pour retrouver de l’information. Et pour finir, nous indiquons également les prototypes des fonctions <strong>Mutations</strong> correspondants aux POST, UPDATE et DELETE d’une API REST.</p><p>Deuxième étape. Créer un fichier de configuration pour utiliser Knex dans les fichiers js, /src/server/db/connection.js, qui contient:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6e5fc1628ae238fd7a012b67f96deece/href">https://medium.com/media/6e5fc1628ae238fd7a012b67f96deece/href</a></iframe><p>Ce fichier nous permet désormais de construire des requêtes Knex en utilisant les fonctions mises à disposition par cet outil.</p><p>Troisième étape. Créer un fichier responsable de la création des requêtes Knex permettant d’interroger la base de données, en fonction de la requête d’entrée envoyée par le client. Créez alors un fichier /src/server/db/queries/queries.js, qui contient:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0361e66cc0c1794b7b3ead3f09f8cc9e/href">https://medium.com/media/0361e66cc0c1794b7b3ead3f09f8cc9e/href</a></iframe><p>Quatrième et dernière étape. Créer un fichier middleware gérant les requêtes reçues par le client. Ce fichier a pour but de récupérer les données de la base de données et de les renvoyer au client. C’est ce fichier qui contient la logique de gestion des requêtes reçues par l’API. Créez donc un fichier /src/server/db/graphql/middlewares.js, contenant:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4f4f566ed4dcc25ff0781cc5f64b0525/href">https://medium.com/media/4f4f566ed4dcc25ff0781cc5f64b0525/href</a></iframe><p><strong>Mise en place du serveur</strong></p><p>C’est bien beau d’avoir une API mais si aucun serveur ne la met à disposition, niveau utilité on repassera. Il vous faut initialiser un serveur en créant un fichier server.js à la racine de votre projet (au même niveau que package.json), qui contient:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8d4f0115edb098a7664d3808289c701b/href">https://medium.com/media/8d4f0115edb098a7664d3808289c701b/href</a></iframe><p>Ici, vous initialisez un serveur sur le port 3000 sur lequel Koa met à disposition trois routes:</p><ul><li>/graphql en GET (route nécessaire pour traiter les <strong>Query</strong>)</li><li>/graphql en POST (route nécessaire pour traiter les <strong>Mutations</strong>)</li><li>/graphiql en GET (route ouvrant une interface permettant de requêter l’API pour effectuer des tests)</li></ul><p>Il vous suffit maintenant de lancer le serveur</p><p>node server.js</p><p>Et voilà ! Vous avez une API GraphQL en NodeJS. Félicitations !</p><h4>Quelques requêtes de test</h4><p>Vous ne voulez qu’une chose c’est tester votre nouvelle API et voir ce qu’elle a dans le ventre. Je vous propose de tester ces quelques requêtes montrant l’utilisation de l’API. N’attendez plus, ouvrez l’interface graphiql en allant sur le lien <a href="http://localhost:3000/graphiql">localhost:3000/graphiql</a>.</p><p>Dans le bloc de gauche vous pouvez écrire la requête que vous souhaitez effectuer, et dans le bloc de droite visualiser la réponse de l’API.</p><p>Commençons par une requête simple permettant de récupérer les auteurs:</p><pre>query {<br> authors {<br>  author_id<br>  first_name<br>  last_name<br> }<br>}</pre><p>Maintenant, plus compliqué, voyons comment récupérer la liste des films avec le détail des commentaires ainsi que des auteurs des commentaires:</p><pre>query {<br> movies {<br>  movie_id<br>  name<br>  genre<br>  rating<br>  explicit<br>  comments {<br>   comment_id<br>   content<br>   author {<br>    author_id<br>    first_name<br>    last_name<br>   }<br>  }<br> }<br>}</pre><p>Génial non ?</p><p>Mais nous n’avons pas encore vu comment envoyer des <strong>Mutations</strong> à l’API. Voyons comment ajouter un commentaire de la part d’un auteur existant:</p><pre>mutation {<br>  addComment(<br>   comment_id: &quot;e8d5b392-885b-40f6-bc87-9048aa5fa789&quot;<br>   content: &quot;Pas de commentaire&quot;<br>   author: &quot;7295d773-5eed-44cf-8b65-dc5d65995cf1&quot;<br>  )<br>  {<br>   comment_id,<br>    content,<br>    author {<br>     author_id,<br>     first_name,<br>     last_name<br>    }<br>  }<br>}</pre><p>Il suffit d’indiquer le nom de la fonction d’ajout de commentaire, de renseigner des paramètres puis de décrire les champs que vous souhaitez récupérer pour une création réussie.</p><p>Et une petite dernière pour la route. Mettre à jour les informations d’un film:</p><pre>mutation {<br> updateMovie(<br>  movie_id: &quot;fce71253-5d65-427f-9c7b-efdc1406306a&quot;<br>  rating: 21<br> )<br> {<br>  movie_id,<br>  name,<br>  genre,<br>  rating,<br>  explicit,<br>  comments {<br>   comment_id<br>  }<br> }<br>}</pre><h4>Conclusion</h4><p>Vous disposez maintenant d’une API GraphQL en NodeJS. Le projet complet se trouve sur <a href="https://github.com/WeCraftApps/graphql-example">Github</a>.</p><p>J’espère que cet exemple vous aura montré que GraphQL est une approche intéressante et qu’elle peut vous éviter bien des maux de têtes par rapport à REST.</p><p>N’hésitez pas à me donner votre avis sur cet article, je débute tout juste dans l’écriture donc tout retour est le bienvenu.</p><p>Belle journée à vous !</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8396dc652fb4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/wecraftapps/une-api-graphql-de-z%C3%A9ro-en-nodejs-8396dc652fb4">Une API GraphQL de zéro en NodeJS</a> was originally published in <a href="https://medium.com/wecraftapps">We Craft Apps</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>