Découvertes de logiciels libres - été 2023

Cet été j’ai eu l’occasion de découvrir de belles pépites de logiciels libres grâce à un changement de travail. Ce nouveau travail était lié à l’affichage de données sur des cartes et des résultats dans des graphiques.

Voici une petite liste de logiciels libres que j’ai pu employer et que j’ai particulièrement appréciés 😊

PostgreSQL, postgis et node-postgres

PostgreSQL est une base de donnée à tout faire, vraiment. Je l’appréciais déjà auparavant pour ses fonctions intégrées de gestion des types JSON, text, large objects, le système pubsub, le système de full text search et ses extensions qui permettent la recherche imprécise (avec faute de frappe, sans casse), la création d’une hiérarchie simple avec un texte comme les path… et, surtout, sa documentation complète et compréhensible.

Cet été, j’en ai découvert une nouvelle facette avec l’extension postgis. Elle permet à PostgreSQL d’enregistrer des données spatiales, de faire des calculs sur les polygones, de créer des rasters et de travailler sur leurs pixels…

node-postgres quant à lui est un client PostgreSQL crée pour Node.js. C’est bien un client SQL et non pas un ORM complexe: il s’occupe juste d’exécuter les requêtes et de transformer en type natif JavaScript ce qui est transformable (les données de type numeric, date, JSON…).

J’apprécie particulièrement qu’il n’essaie pas de faire de choses intelligentes comme gérer du cache ou créer des objets automatiquement: mine de rien, le fait que le client soit simple permet de le maitriser plus facilement (la courbe d’apprentissage est petite).

Un point que je trouve vraiment très fort est son plugin pg-query-stream qui permet de faire passer facilement à travers le réseau une requête qui génère des résultats de grande taille. Les Stream permet d’éviter de faire monter tous les résultats dans la mémoire de PostgreSQL et de celle de Node.js.

Curseur PostgreSQL ---[réseau]--> pg-query-stream -> JSONStream -> HTTP Response stream ---[réseau]--> HTTP client

Du côté de PostgreSQL, pg-query-stream utilise un curseur SQL pour récupérer les résultats à mesure que la requête s’exécute. Ensuite, du côté Node.js, pg-query-stream retourne un Readable Stream. Ce stream peut être enchaîné avec un Transformer Stream qui crée un objet JSON avec le résultat binaire de chaque ligne de réponse SQL. Enfin, ce stream peut lui-même être enchaîné avec le Writable Stream de l’objet HTTP Response de Node.js qui s’occupe d’envoyer au fur et à mesure les données au client HTTP (avec une réponse HTTP de type application/octet-stream).

Grâce à ce système de stream, il n’y a pas de surcharge mémoire quand une grande liste d’objet est demandée et ce ni sur le serveur PostgreSQL, ni sur le serveur de l’API. Le client HTTP quant à lui reçoit les premières données dès qu’elles sont prêtes, il n’aura pas besoin d’attendre de recevoir les données complètes avant de commencer la mise à jour de son affichage.

Node.js et ses stream

Ça fait maintenant 3 ans que je travaille avec Node.js (depuis la version 12) et j’apprécie beaucoup son API et son écosystème.

Il a bien sûr son lot de points négatifs comme le fait qu’un projet peu très facilement tirer des milliers de sous-dépendances. Pour ce point, les gestionnaires de dépendances font du bon travail et ne m’ont jamais posé problèmes (j’ai trouvé bien plus simple l’utilisation de npm et yarn que celles de pip et virtual env de Python ou celles de gem et bundler de Ruby).

La documentation de Node.js est vraiment très complète et bien structurée ! J’apprécie vraiment de pouvoir m’appuyer sur cette documentation pour bien appréhender ce qui est possible de faire et à partir de quelle version de Node.js.

Le système de stream de Node.js présenté plus haut est aussi plutôt bien pensé (ça ressemble au fonctionnement des pipes de Linux) et je l’apprécie beaucoup, car il permet également de créer ses propres streams facilement. Il y a pas mal de documentation à lire quand on implémente pour la première fois une extension de Readable et Writable, mais le code final est bien organisé: les classes de base de Node.js s’occupent de la gestion du stream et les classes d’extensions ne s’occupent que de la lecture ou l’écriture des données.

Par exemple, j’ai eu besoin d’importer dans PostgreSQL un historique de donnée sous format CSV avec un traitement à effectuer entre deux. Le fichier CSV avait tellement de donnée qu’il dépassait la limite de lignes lisibles par LibreOffice Calc.

Pour lire le CSV, j’ai donc utilisé l’outil csv-parser qui permet de lire le fichier avec un Readable Stream.

En implémentant les fonctions _write et _final, j’ai été capable de créer un Writable Stream qui prépare les requêtes nécessaires en lisant les données et les envoient régulièrement en bloque au serveur PostgreSQL.

Enfin, il faut chainer les deux Stream pour avoir un outil qui puisse lire le CSV tout en envoyant à mesure de la lecture les requêtes SQL pour enregistrer les nouvelles données en base.

Frontend avec Vue.js 3

J’ai pour la première fois créé le frontend d’une application avec un framework JavaScript. J’ai trouvé que Vue.js est un cadriciel qui permet de bien structurer son application et qui aide à faire les liens entre les éléments DOM et le code JavaScript de manière efficace.

De nouveau, sa documentation est bien faite et elle n’est pas trop longue à lire.

Vue.js m’a permis de découvrir comment bien utiliser la composition pour éviter de créer des hiérarchies complexes d’objets tout en gardant un code avec peu de répétitions.

Un autre point appréciable est qu’il est plutôt aisé de créer un Component qui intègre des outils JavaScript qui n’ont pas été développés pour Vue.js. Par exemple, mes collègues ont pu intégrer de manière efficace des outils complexes comme OpenLayers et Chart.js.

Pour ma part, j’ai pu faire l’intégration de noUiSlider pour permettre aux utilisateurs d’utiliser ce curseur avancé pour naviguer à travers des graphes de données temporelles. Pour faire cette intégration, je me suis reposé sur Vueform slider, parce que j’avais d’abord trouvé cet outil. Ce n’est que plus tard que j’ai découvert qu’il était une intégration de noUiSlider dans Vue.js. Si c’était à refaire, je ferai directement l’intégration de noUiSlider pour avoir plus de souplesse (j’avais une limitation sur l’intégration des pips que Vueform slider n’avait semble-t-il pas prévu dans son intégration).

OpenLayers

OpenLayers est un projet complexe qui permet d’intégrer une carte du monde dans son site web et d’ajouter au-dessus des couches interactives. Le sujet étant lui-même complexe, je trouve qu’OpenLayers est un très bon projet et qu’il aurait été difficile de faire plus simple.

J’ai été impressionné de réussir à intégrer des objets SVG et dynamiques dans le <canvas> d’OpenLayers.

Un souci que nous avions était de réussir à faire télécharger des images d’un serveur d’image avec un token d’authentification à ajouter dans un Header HTTP. Or le navigateur n’avait pas lui-même authentifié l’utilisateur: il ne pouvait donc pas lui-même se charger de passer du bon en-tête Authorization. On ne pouvait pas simplement utiliser l’API Fetch du navigateur non plus, car on devait lui dire d’ajouter pour chaque requête du bon en-tête.

Eh bien, OpenLayers est assez souple pour lui donner une méthode alternative pour télécharger les images et le faire de manière authentifiée grâce au module axios que nous utilisions déjà pour les autres requêtes vers notre API.

Chart.js

Chart.js est un outil que j’ai eu assez de peine à comprendre comment bien l’utiliser. Il permet d’intégrer un graphique avec des données dans un <canvas>.

Sa documentation est plutôt fouillis et il est difficile de trouver la page qui donnera la bonne information sur la configuration.

Cependant, quand j’ai commencé à comprendre leur philosophie pour la configuration et les bons termes pour les parties que je voulais changer, j’ai trouvé que l’outil était plutôt bien fait.

Le graphe de base n’est pas dynamique, mais j’ai pu l’assembler avec le curseur noUiSlider pour mettre à jour dynamiquement les bornes d’affichage de l’axe x. Là, j’ai découvert que Chart.js fait très bien son travaille et qu’il arrivait de manière fluide à suivre les mises à jour que le curseur lance durant son glissement.

noUiSlider

Durant mon projet, j’avais besoin de créer un ascenseur horizontal pour naviguer à travers des dates sur 3 ans.

En lisant MDN, j’ai appris que HTML 5 proposait déjà un <input type="range"> pour créer un slider sur des valeurs numériques. La documentation donne même un exemple avec <datalist> pour lier des textes à des valeurs numériques.

J’étais assez emballé par cet outil, mais malheureusement, il ne permet pas beaucoup de stylisation et je ne pouvais donc pas facilement l’intégrer dans notre application web et supporter plusieurs navigateurs.

En plus, j’avais besoin d’un slider qui permette de choisir deux valeurs pour définir un range de date à visualiser et non pas juste une seule date.

noUiSlider est un outil JavaScript qui permet de créer des sliders avec beaucoup plus de flexibilité et, surtout, permet de le styliser de manière simple.

noUiSlider est beaucoup plus précis pour l’affichage des marqueurs et des textes puisqu’il gère lui-même toute l’intégration avec le slider.

A contrario, l’exemple ci-dessus avec HTML et CSS utilise une flexbox de CSS pour répartir de manière proportionnelle les valeurs de <datalist> sur la même largeur que l’élément <input>. Comme les affichages de ces deux éléments HTML ne sont pas vraiment liés, il est très difficile de placer les marqueurs de manière exacte et il est nécessaire d’avoir toujours un espace équivalent entre chaque marqueur.

Commentaires

Vous pouvez ajouter un commentaire avec votre compte Fediverse sur ce message.