<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jean-François Le Foll</title>
    <description>The latest articles on DEV Community by Jean-François Le Foll (@jefflefoll).</description>
    <link>https://dev.to/jefflefoll</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F149488%2Fb8d447af-55a7-4ff1-b3c0-7b4c8845c15c.jpg</url>
      <title>DEV Community: Jean-François Le Foll</title>
      <link>https://dev.to/jefflefoll</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jefflefoll"/>
    <language>en</language>
    <item>
      <title>Pourquoi écrire des Documents de Choix d'Architecture ? (Architecture Decision Record)</title>
      <dc:creator>Jean-François Le Foll</dc:creator>
      <pubDate>Wed, 16 Jun 2021 13:50:22 +0000</pubDate>
      <link>https://dev.to/avalon-lab/pourquoi-ecrire-des-documents-de-choix-d-architecture-architecture-decision-record-101c</link>
      <guid>https://dev.to/avalon-lab/pourquoi-ecrire-des-documents-de-choix-d-architecture-architecture-decision-record-101c</guid>
      <description>&lt;h2&gt;
  
  
  Tout d'abord qu'est-ce qu'un ADR ?
&lt;/h2&gt;

&lt;p&gt;La base de notre métier est de faire des choix : choix de technologie, choix d'architecture, choix d'implémentation...&lt;br&gt;
Certains sont plus impactants que d'autres.&lt;/p&gt;

&lt;p&gt;Le but d'un ADR est de documenter et de tracer le raisonnement derrière ces choix, en gardant le contexte du niveau de connaissance et de maîtrise du sujet au moment de ce choix.&lt;br&gt;
Quel était mon problème ? Quelles étaient les différentes solutions envisagées ? Quels éléments nous ont amenés vers ce choix ?&lt;/p&gt;

&lt;h2&gt;
  
  
  Quel formalisme pour un ADR ?
&lt;/h2&gt;

&lt;p&gt;Un ADR, c'est un document texte, facile à partager au sein de l'équipe (dans un wiki ou dans un repository par exemple).&lt;/p&gt;

&lt;p&gt;C'est un document immuable, il n'a pas vocation à être mis à jour, au mieux le statut peut changer si cette décision est remplacée par une autre.&lt;/p&gt;

&lt;p&gt;Le titre de l'ADR doit être explicite : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;choix_langage_backend&lt;/li&gt;
&lt;li&gt;choix_base_de_données&lt;/li&gt;
&lt;li&gt;gestion_des_dates&lt;/li&gt;
&lt;li&gt;format_des_logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Décrivez clairement le contexte, pourquoi cette décision se pose, quel problème / contrainte essayons nous de résoudre ?&lt;/p&gt;

&lt;p&gt;Décrivez le raisonnement qui vous amène à votre décision, n’hésitez pas à lister les expérimentations que vous avez faites, les articles sur lesquels vous vous êtes basés, tout ce qui vous permettra de comprendre votre décision si vous relisez l'ADR dans 6 mois.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ce sont pour moi, les trois parties les plus importantes d'un ADR : titre, contexte, raisonnement/décision&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vous pouvez également décrire les conséquences qu'aura ce choix (par exemple nouvelle contrainte ou nouvelle complexité).&lt;br&gt;
Vous pouvez aussi ajouter un statut à votre ADR (accepté, rejeté, déprécié, remplacé...).&lt;/p&gt;

&lt;p&gt;Vous pouvez trouver des modèles d'ADR beaucoup plus détaillés sur internet, mais au final c'est vous et votre équipe qui allez les écrire et les lire donc choisissez les rubriques qui sont pertinentes pour vous.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Dans un contexte en constante évolution, où nous apprenons de nouvelles choses régulièrement (sur les besoins des utilisateurs, sur les technos, ...), pouvoir pourquoi et comment tel ou tel choix a été fait est important pour une équipe et sa compréhension de son produit.&lt;br&gt;
C'est aussi une source d'information pratique pour les nouveaux arrivants dans l'équipe.&lt;/p&gt;




&lt;p&gt;D'un point de vue personnel, chez Avalon Lab, nous sommes des prestataires, nous accompagnons des entreprises et porteurs de projets qui n'ont pas forcément d'équipe technique.&lt;br&gt;
Dans ce cas, les ADR nous permettent de documenter tous les choix technologiques et d'architectures que nous prenons, car finalement ce n'est pas nous qui allons vivre avec ces choix, mais bien les développeurs·euses qui seront recruté·e·s plus tard par le client. &lt;br&gt;
Les ADR leurs permettrons de comprendre comment et pourquoi le produit est ce qu'il est.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Pour aller plus loin sur le sujet des ADR : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://adr.github.io/"&gt;ADR GitHub organization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/joelparkerhenderson/architecture-decision-record"&gt;Architecture decision record (ADR)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Cover Photo by &lt;a href="https://unsplash.com/@kaleidico?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Kaleidico&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>architecture</category>
      <category>documentation</category>
      <category>adr</category>
    </item>
    <item>
      <title>CTO d'amorçage / Team as a Service, qu'est-ce que c'est ?</title>
      <dc:creator>Jean-François Le Foll</dc:creator>
      <pubDate>Wed, 13 May 2020 14:57:45 +0000</pubDate>
      <link>https://dev.to/avalon-lab/cto-d-amorcage-team-as-a-service-qu-est-ce-que-c-est-42jd</link>
      <guid>https://dev.to/avalon-lab/cto-d-amorcage-team-as-a-service-qu-est-ce-que-c-est-42jd</guid>
      <description>&lt;p&gt;Le principe du CTO d'amorçage / Team as a Service est d'intervenir, à minima en binôme, dans une structure sans compétence disponible en développement logiciel (développement, gestion de projet, etc ...) afin de démarrer un projet, d'accompagner le client sur le développement et la conception de son produit ou MVP, de poser les bases d'une architecture saine et éventuellement de l'aider dans son recrutement de développeurs.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j273nhM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dfokm7boeba8w6aslb4i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j273nhM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dfokm7boeba8w6aslb4i.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nous avons abordé notre action de CTO d'amorçage / Team as a Service suivant trois axes : tout d'abord d'un point de vue apprentissage fonctionnel, puis d'un point de vue méthodologique et enfin d'un point de vue technique.&lt;/p&gt;

&lt;h1&gt;
  
  
  Apprentissage fonctionnel
&lt;/h1&gt;

&lt;p&gt;Le métier de ce client était quelque chose de nouveaux pour nous, nous avons donc fait plusieurs ateliers d'Event Storming avec l'expert métier.  &lt;/p&gt;

&lt;p&gt;Le but de ces ateliers est multiple :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Découvrir le langage métier de l'expert (et donc partager le même langage entre le code et la réalité métier)&lt;/li&gt;
&lt;li&gt;Découvrir le fonctionnement de l'outil, le process métier, les besoins&lt;/li&gt;
&lt;li&gt;Avoir une première idée / ébauche de la conception du logiciel&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ceci s'inscrit dans une approche Domain-Driven Design (DDD) ou Conception pilotée par le domaine (métier).&lt;/p&gt;

&lt;p&gt;Ces ateliers sont refaits régulièrement, par exemple pour présenter un nouveau use case afin d'en explorer le fonctionnement.&lt;/p&gt;

&lt;h1&gt;
  
  
  Méthodologie
&lt;/h1&gt;

&lt;p&gt;Chez Avalon Lab, nous sommes convaincus par les principes de développement agile.&lt;br&gt;&lt;br&gt;
Nous avons un fonctionnement assez proche de la méthode eXtrem Programming :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contact étroit avec l'expert métier&lt;/li&gt;
&lt;li&gt;Livraison fréquente&lt;/li&gt;
&lt;li&gt;Feedback régulier&lt;/li&gt;
&lt;li&gt;Binômage&lt;/li&gt;
&lt;li&gt;Développement piloté par les tests (TDD)&lt;/li&gt;
&lt;li&gt;Intégration et déploiement continue&lt;/li&gt;
&lt;li&gt;Rythme soutenable&lt;/li&gt;
&lt;li&gt;Conception simple&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Intervenant dans un contexte "remote" dès le départ, l'expert métier n'étant pas localisé avec l'équipe de développement, nous avons mis en place plusieurs outils afin de collaborer efficacement en fonction des contraintes client :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gitlab (gitlab.com), pour la gestion de projets (user stories, bug tracker, milestone)&lt;/li&gt;
&lt;li&gt;Miro (miro.com), un tableau blanc collaboratif (schémas, atelier post-it)&lt;/li&gt;
&lt;li&gt;Skype ou autre, notamment pour faire des démos, via le partage d'écran.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Technique
&lt;/h1&gt;

&lt;p&gt;L'approche DDD, notamment au travers d'ateliers type Event Storming, nous permet de mieux concevoir l'application.&lt;br&gt;&lt;br&gt;
L'application est découpée en domaine, unités logiques correspondant à un regroupement logique de sens métier.&lt;/p&gt;

&lt;p&gt;Pour implémenter ces domaines, nous avons suivi les principes de l'architecture hexagonale où tout le code, correspondant aux règles métier, est correctement isolé de l'extérieur (base de données, web services, interface utilisateur) et n'est pas "pollué" par du code provenant d'un quelconque framework ce qui rend les choix de solutions type framework moins définitive et impactant.&lt;/p&gt;

&lt;p&gt;Aujourd'hui, on sait que les fonctions principales d'un logiciel concernent principalement de la présentation de données (certains parlent de 80 % lecture de données et 20 % écriture de données).&lt;/p&gt;

&lt;p&gt;Partant de ce constant, nous avons adopté le pattern CQRS (Command Query Responsibility Segregation) qui sépare les tâches d'écriture (command), des tâches de lecture (query) et ayant des modèles de donnés séparés.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;[Ce pattern peut être étendu avec le principe d'Event Sourcing lorsque le métier requiert un traçage / audit des différentes actions.]&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Toutes les décisions d'architectures / de choix techniques sont tracés dans des documents de décision d'architecture (Architecture decision record - &lt;a href="https://github.com/joelparkerhenderson/architecture_decision_record"&gt;ADR&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture SI
&lt;/h3&gt;

&lt;p&gt;L'architecture physique du SI évolue en fonction des besoins métier, tout en se basant sur les principes généraux des &lt;a href="https://12factor.net/fr/"&gt;12 factors&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Nous avons d'un côté un frontal web (SPA) et de l'autre un backend métier.&lt;/p&gt;

&lt;p&gt;Pour le backend métier, notre principe de base est de démarrer avec un monolithe, comme nous adoptons une démarche DDD, ce monolithe embarque nos domaines qui eux sont indépendants et correctement séparés.&lt;br&gt;&lt;br&gt;
L'avantage est de simplifier la phase de construction de l'application ainsi que sont déploiement et son monitoring tout en gardant la flexibilité de pouvoir sortir un domaine afin de répondre à un nouveau besoin ou à des contraintes de charges spécifiques.&lt;/p&gt;

&lt;p&gt;De plus, cette architecture est déclinée en deux versions :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test/intégration =&amp;gt; construite directement depuis les sources, à chaque modification (Continuous Deployement), permet aux développeurs et à l'expert métier de tester sur un environnement déployé.&lt;/li&gt;
&lt;li&gt;Production =&amp;gt; construite et déployée à la demande, ouverte aux clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Technologie
&lt;/h3&gt;

&lt;p&gt;Dans l'optique d'aider le client à recruter des développeurs et un CTO, nous sommes partis sur des technologies fiables, connues et pour lesquelles il est facile de recruter tout en respectant nos critères de qualités.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VueJS / Web Component (lit-element)&lt;/li&gt;
&lt;li&gt;Java 11&lt;/li&gt;
&lt;li&gt;Gitlab : gestion de code et ci/cd&lt;/li&gt;
&lt;li&gt;Datadog : collecte et analyse des logs applicatives / monitoring &lt;strong&gt;&lt;em&gt;[peut être remplacé par Elastic Stack]&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Clever Cloud : gestion de l'infrastructure&lt;/li&gt;
&lt;li&gt;Izanami : Configuration partagée, features flipping&lt;/li&gt;
&lt;li&gt;Warp10 : Base de données de séries temporelles&lt;/li&gt;
&lt;li&gt;Cellar / AWS S3 : stockage de fichiers&lt;/li&gt;
&lt;li&gt;SonarCloud : Analyse qualité du code
&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;Cet article vous a intéressé, vous avez envie d'en savoir plus ou par rapport à vos besoins ?&lt;br&gt;&lt;br&gt;
N'hésitez pas à nous envoyer un mail à &lt;a href="mailto:contact@avalon-lab.coop"&gt;contact@avalon-lab.coop&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>cto</category>
      <category>esn</category>
      <category>service</category>
    </item>
    <item>
      <title>Server-Sent Events démystifiés, avec un cas concret.</title>
      <dc:creator>Jean-François Le Foll</dc:creator>
      <pubDate>Wed, 11 Mar 2020 16:18:28 +0000</pubDate>
      <link>https://dev.to/avalon-lab/server-sent-events-demystifies-avec-un-cas-concret-402</link>
      <guid>https://dev.to/avalon-lab/server-sent-events-demystifies-avec-un-cas-concret-402</guid>
      <description>&lt;h1&gt;
  
  
  Préface
&lt;/h1&gt;

&lt;p&gt;Avant d'aller plus loin, expliquons d'abord ce que sont les Server-sent Events (SSE pour les intimes).&lt;/p&gt;

&lt;p&gt;Il s'agit d'un canal unidirectionnel permettant au serveur d'envoyer des messages à un navigateur.&lt;/p&gt;

&lt;p&gt;C'est une techno ancienne, qui date de 2009-2010 et est disponible au grand public depuis les versions 6 de Chrome et Firefox, mais qui a été un peu mise de coté à l'arrivée des WebSockets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2TCgqWag--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nw4l78nremv2lpsn8502.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2TCgqWag--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/nw4l78nremv2lpsn8502.JPG" alt="Alt Text" width="880" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Objectif ?
&lt;/h1&gt;

&lt;p&gt;Le but de cette démo est de construire un cas concret d'utilisation de SSE.&lt;br&gt;
Beaucoup d'articles ou de démos que j'ai pu trouver ne montrent guère autre chose qu'un event pré-construit envoyé à intervalle régulier, pas grand-chose à voir avec la réalité.&lt;/p&gt;

&lt;p&gt;Dans cette démo, nous allons construire une API Rest, qui poussera un message dans un RabbitMQ en mode Fan-out.&lt;br&gt;
De l'autre coté, nous aurons un serveur nodejs qui écoutera les messages et poussera un SSE au bon client de la webapp servi par le nodejs.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mY9zZemB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3nugak40uy99zb18827b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mY9zZemB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/3nugak40uy99zb18827b.png" alt="Alt Text" width="880" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dans l'objet poussé sur l'endpoint, nous avons un client ID, ce qui permet d'avoir plusieurs onglets ouverts sur la web app et ainsi voir que les SSE arrivent seulement au bon client.&lt;/p&gt;
&lt;h1&gt;
  
  
  Le code :
&lt;/h1&gt;
&lt;h3&gt;
  
  
  L'API Rest
&lt;/h3&gt;

&lt;p&gt;Je ne vais pas entrer ici dans les détails de l'API Rest, c'est une API Java (&lt;a href="https://jooby.io"&gt;Jooby 2&lt;/a&gt;) qui sert de producer RabbitMQ.&lt;/p&gt;
&lt;h3&gt;
  
  
  La Web App
&lt;/h3&gt;

&lt;p&gt;Il s'agit d'une simple page html avec un Web Component (les dépendances sont chargées directement avec &lt;a href="https://www.pika.dev/"&gt;Pika&lt;/a&gt;, cela peut prendre quelques secondes).&lt;/p&gt;

&lt;p&gt;Pour se connecter à un endpoint SSE, rien de plus simple, il suffit de définir un &lt;a href="https://developer.mozilla.org/fr/docs/Web/API/EventSource"&gt;&lt;code&gt;EventSource&lt;/code&gt;&lt;/a&gt; qui prend en paramètre l'url de la source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sseSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EventSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/event-stream/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Dans notre cas, nous ajoutons dans l'url le clientId du client connecté.&lt;/p&gt;

&lt;p&gt;Sur cet objet EventSource nous allons venir définir un event listener, le but est de ne réagir qu'aux messages de type &lt;code&gt;notif&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;sseSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notif&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notifications&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notifications&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ce code nous permet d'incrémenter un compteur et d’alimenter un tableau avec le message de l’événement. &lt;br&gt;
C'est tout pour la partie front.&lt;/p&gt;
&lt;h3&gt;
  
  
  La partie serveur NodeJs
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1) Le point d'entrée SSE
&lt;/h4&gt;

&lt;p&gt;Ici on utilise ExpressJS car il n'y rien de particulier à faire pour mettre en place la ressource SSE :&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/event-stream/:clientId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cache-Control&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no-cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keep-alive&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Connection open for client : &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ici nous définissons notre ressource &lt;code&gt;GET "/event-stream/:clientId"&lt;/code&gt; avec un paramètre &lt;code&gt;clientId&lt;/code&gt; qui nous permet de stocker l'objet &lt;code&gt;response&lt;/code&gt; sur lequel envoyer les messages :&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Mais avant de stocker cette réponse, il faut la "configurer" pour le SSE :&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cache-Control&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no-cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keep-alive&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Pour résumer cette partie, à chaque fois qu'un client fait un &lt;code&gt;GET&lt;/code&gt; sur notre ressource SSE, nous stockons dans un objet sont &lt;code&gt;clientId&lt;/code&gt; et l'objet &lt;code&gt;response&lt;/code&gt; afin de lui pousser des messages ultérieurement.&lt;/p&gt;
&lt;h4&gt;
  
  
  2) Le consumer RabbitMQ
&lt;/h4&gt;

&lt;p&gt;Afin de pouvoir se connecter sur le RabbitMQ, nous allons avoir besoin de la dépendance vers la librairie &lt;code&gt;amqplib&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amqp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amqplib/callback_api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; fonctionne avec des callback&lt;/span&gt;
&lt;span class="c1"&gt;// ou&lt;/span&gt;
   &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amqp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amqplib&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// =&amp;gt; fonctionne avec des promesses&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Au démarrage du serveur nodejs, on ouvre une connexion vers RabbitMQ&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;amqp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;amqp://localhost&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Dans cette connexion, on va créer un channel sur notre Exchange et une Queue (Cf dépôt Github pour le code de cette partie).&lt;/p&gt;

&lt;p&gt;Ce qui nous intéresse ici, c'est de voir comment on consomme les messages.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;      &lt;span class="nx"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New message for client : &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;clientRes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;connections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clientRes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;clientRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`event: notif\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="nx"&gt;clientRes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`data: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;noAck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;On va parser le message pour en récupérer le contenu, grâce au &lt;code&gt;clientId&lt;/code&gt; du message, on récupère notre objet &lt;code&gt;response&lt;/code&gt; qui correspond.&lt;br&gt;
Si elle existe, on vient écrire une première ligne avec le type d'événement &lt;code&gt;clientRes.write('event: notif\n');&lt;/code&gt; (pour rappel notre front n'écoute que les messages &lt;code&gt;notif&lt;/code&gt;).&lt;br&gt;
Puis une seconde ligne avec le contenu du message &lt;code&gt;clientRes.write('data: ${data.content}\n\n');&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Et voilà, nous avons poussé notre message dans notre stream d'événements.&lt;br&gt;
Le front réagi, incrémente le compteur et affiche le message !&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T7DS3eBB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s4kwhq47efy8hcu13w52.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T7DS3eBB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/s4kwhq47efy8hcu13w52.JPG" alt="Alt Text" width="642" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J'espère que maintenant l'utilisation des SSE est un peu plus claire et concrète pour vous aussi :)&lt;/p&gt;



&lt;p&gt;Le code de la démo complète est disponible sur GitHub : &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Avalon-Lab"&gt;
        Avalon-Lab
      &lt;/a&gt; / &lt;a href="https://github.com/Avalon-Lab/realtime-webapp-sse-rabbitmq"&gt;
        realtime-webapp-sse-rabbitmq
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Demo WebApp temps réel avec SSE et RabbitMQ
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>sse</category>
      <category>rabbitmq</category>
      <category>reactivewebapp</category>
      <category>usecase</category>
    </item>
    <item>
      <title>Retour sur SoCraTesDay à Rennes</title>
      <dc:creator>Jean-François Le Foll</dc:creator>
      <pubDate>Wed, 06 Nov 2019 14:56:36 +0000</pubDate>
      <link>https://dev.to/avalon-lab/retour-sur-socratesday-a-rennes-3ofg</link>
      <guid>https://dev.to/avalon-lab/retour-sur-socratesday-a-rennes-3ofg</guid>
      <description>&lt;p&gt;Vendredi 14 juin, j'ai eu la chance de participer à la première SoCraTesDay à Rennes.&lt;br&gt;&lt;br&gt;
Un forum ouvert d'une journée, autour du développement logiciel, des tests, de la qualité du code et du software craftsmanship.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Un forum ouvert ? Qu'est-ce que c'est ?
&lt;/h2&gt;

&lt;p&gt;Un forum ouvert est une façon de structurer une conférence, sans speakers, où les participants construisent eux-mêmes leurs programmes en fonction de leurs connaissances et de ce qu'ils ont envie d'apprendre / échanger.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Une conférence dont vous êtes le héros !  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Chacun affiche le(s) sujet(s), dont il a envie de parler sur un tableau (appelé Marketplace), aux intersections entre des créneaux horaires et des espaces nommés.  &lt;/p&gt;

&lt;p&gt;Marketplace du SoCraTes Rennes :  &lt;/p&gt;

&lt;p&gt;Liquid error: internal&lt;/p&gt;

&lt;p&gt;Cet &lt;em&gt;"agenda"&lt;/em&gt; continu de se construire au fil de la journée. En fonction des discussions, de nouveaux post-it vont être ajoutés pour approfondir certains sujets par exemple ou parce qu'une session a fait émerger une nouvelle idée à sur laquelle un groupe a envie de discuter.  &lt;/p&gt;

&lt;p&gt;Les règles de ce genre d'événement sont assez simples. En plus du respect et de la bienveillance, on retrouve également :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Quand c'est fini, c'est fini&lt;/em&gt; : il est important, à la fin de son créneau horaire, de s'arrêter pour laisser la place au groupe suivant. Ça ne veut pas dire pour autant qu'il faille arrêter la discussion, au contraire, il suffit simplement de trouver un espace libre pour continuer&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;La loi des deux pieds&lt;/em&gt; : à tous moments, vous êtes libre de suivre vos deux pieds pour quitter une session afin de rejoindre une autre session ou autre.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  SoCraTesDay, on y parle de quoi ?
&lt;/h2&gt;

&lt;p&gt;Et bien c'est ça qui est vraiment intéressant c'est qu'on y parle de tout ce dont les participants ont envie.   &lt;/p&gt;

&lt;p&gt;Personnellement, j'ai tendance à découper les sujets en trois catégories.  &lt;/p&gt;

&lt;h2&gt;
  
  
  La technique, les outils
&lt;/h2&gt;

&lt;p&gt;Lors de ce SoCraTest, il y a eu des sessions d'introductions à ELM et Rust, des katas de refacto de code legacy, des discussions autour des backends js, du code source de spring boot, de la gestion des logs avec ELK.  &lt;/p&gt;

&lt;h2&gt;
  
  
  La conception, l'architecture, les méthodes
&lt;/h2&gt;

&lt;p&gt;Il y a des sessions sur le BDD (pas les bases de données, mais le Behaviour Driven Development), sur le DDD en mode introduction sur les concepts stratégiques puis comment démarrer concrètement après, sur le TDD (voilà on fait le tour des xDD ;) ), sur les archis hexagonales, les archis micro-frontend, sur les tests e2e, sur la stabilité des logiciels, sur l'agilité (notamment sur les Scrum Masters qui ne font pas de dev).  &lt;/p&gt;

&lt;h2&gt;
  
  
  La pratique, le métier, l'éthique
&lt;/h2&gt;

&lt;p&gt;Enfin, il y a eu des discussions autour de la veille, du bonheur au travail, de qu'est-ce qu'un bon développeur, sur le mentoring, alternative au salariat ? (indépendant, monter sa boite), sur l'impact écologique des logiciels et le low tech et un retour d'expérience sur une organisation horizontale.  &lt;/p&gt;

&lt;h2&gt;
  
  
  À quoi a ressemblé ton SoCraTesDay ?
&lt;/h2&gt;

&lt;p&gt;Le temps de discuter un peu, de regarder la construction du market place, je suis arrivé sur la fin de la discussion concernant le principe de micro-frontend.  &lt;/p&gt;

&lt;p&gt;J'ai enchaîné ensuite sur la session DDD que j'avais proposé, car c'est mon intérêt du moment, remettre le métier du client au cœur de notre pratique et de notre code, parler le même langage que l'expert métier, sont des choses que je trouve importantes et presque toute ma veille du moment tourne autour de ce sujet.&lt;br&gt;&lt;br&gt;
Cette session était plutôt basée sur les concepts stratégiques : comment exprimer les domaines, contextes métiers, notamment via des Event Storming. Elle a suscité une deuxième session, plus "tactique" où on a parlé d'User Stories Mapping, de slicing horizontal, d'architecture à Uses Cases.  &lt;/p&gt;

&lt;p&gt;J'ai terminé la matinée par les sessions sur les Object Calisthenics et comment construire une roadmap dans une approche MVP.  &lt;/p&gt;

&lt;p&gt;L'après-midi, j'ai participé à la session sur les alternatives au salariat. Le groupe était assez hétérogène avec des salariés de boites classiques, de boites "un peu plus ouvertes", des indépendants (ou ex-indé) et moi en SCOP.&lt;br&gt;&lt;br&gt;
On a eu beaucoup d'échanges très constructifs, des retours d'expériences enrichissants car on n'avait pas tous le même vécu, rencontré les mêmes problématiques.  &lt;/p&gt;

&lt;p&gt;Au-delà du market place, il y a aussi toutes les discussions impromptues dans l'espace commun, l'occasion de faire plein de rencontres intéressantes.  &lt;/p&gt;

&lt;h2&gt;
  
  
  En conclusion ?
&lt;/h2&gt;

&lt;p&gt;Il s'agissait de ma seconde journée de forum ouvert après NewCrafts Bordeaux de l'année dernière et je dois dire que j'apprécie vraiment beaucoup ce format de conférence qui est vraiment basé sur les discussions, les échanges contrairement à une conférence traditionnelle où on écoute un speaker pendant 45 minutes.  &lt;/p&gt;

&lt;p&gt;Rendez-vous à &lt;a href="https://bordeaux.ncrafts.io/"&gt;NewCrafts Bordeaux&lt;/a&gt; en octobre maintenant ;)  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Article publié originellement sur &lt;a href="https://medium.com/avalonlab/retour-sur-socrates-day-rennes-23d0d988dec4"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>socrates</category>
      <category>unconference</category>
      <category>softwaredevelopment</category>
      <category>french</category>
    </item>
    <item>
      <title>Qui sommes-nous ?</title>
      <dc:creator>Jean-François Le Foll</dc:creator>
      <pubDate>Wed, 06 Nov 2019 14:32:23 +0000</pubDate>
      <link>https://dev.to/avalon-lab/qui-sommes-nous-afe</link>
      <guid>https://dev.to/avalon-lab/qui-sommes-nous-afe</guid>
      <description>&lt;p&gt;Nous sommes &lt;strong&gt;un studio de développement logiciel&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nous sommes &lt;strong&gt;trois développeurs passionnés&lt;/strong&gt; qui travaillent ensemble depuis déjà plusieurs années et qui ont décidé de monter leur structure afin de mettre en pratique leur conception du métier de développeur et de la façon de construire des logiciels.&lt;/p&gt;

&lt;p&gt;Nous considérons qu'apprendre est notre métier, apprendre de nouvelles technologies mais également une ouverture d'esprit et une curiosité pour comprendre le métier de nos interlocuteurs et échanger avec eux. Au fil des années nous avons travaillé dans des domaines très variés et fait de nombreuses rencontres humaines : pour nous, c'est aussi ce qui rend notre travail intéressant.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2ijK7X0j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yk6zuuc69hh5y1o25gyk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2ijK7X0j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yk6zuuc69hh5y1o25gyk.jpeg" alt="L’équipe Avalon Lab" width="880" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Que fait-on ?
&lt;/h2&gt;

&lt;p&gt;Nous réalisons vos projets logiciels avec vous, en mettant en place une &lt;strong&gt;co-construction&lt;/strong&gt; itérative et agile, basée sur les principes d'&lt;strong&gt;&lt;a href="https://ronjeffries.com/xprog/what-is-extreme-programming/"&gt;eXtrem Programming&lt;/a&gt;&lt;/strong&gt; et du &lt;strong&gt;Software Craftsmanship&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Nous vous accompagnons également vos équipes sur la mise en place de bonnes pratiques agiles et techniques issues d'XP (développement itératif, livraison constante de valeur, TDD, pair programming, ...).&lt;/p&gt;

&lt;p&gt;Pour nous, la meilleure façon de construire un logiciel passe par une bonne communication entre les différents acteurs ainsi que par la mise en place d'équipes de développeurs auto-organisés, responsables, ayant le contrôle/pouvoir sur leur travail de tous les jours.&lt;/p&gt;

&lt;p&gt;En nous basant sur ce principe qui nous est cher, nous nous sommes constitués sous forme de &lt;strong&gt;Société COopérative et Participative&lt;/strong&gt; (SCOP), afin de laisser à chacun la possibilité de prendre part aux décisions de l'entreprise, dans la transparence la plus totale.&lt;/p&gt;

&lt;p&gt;Jean-François, Mathieu, Jérémy.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Article publié originellement sur &lt;a href="https://medium.com/avalonlab/qui-sommes-nous-c4a72c91cf6d"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>scop</category>
      <category>développementlogiciel</category>
      <category>nossii</category>
      <category>french</category>
    </item>
  </channel>
</rss>
