Le nouveau backend de TSBOARD, le builder de communautés open source : GOAPI
(github.com/sirini)J’ai présenté pour la première fois le projet TSBOARD il y a environ 7 mois.
À l’époque, le frontend comme le backend étaient tous deux écrits en TypeScript, et le runtime Bun était utilisé pour faire tourner le backend.
Cependant, pour diverses raisons, j’ai dû reconstruire entièrement le backend, et je le publie dans un dépôt GitHub séparé de l’ancien projet TSBOARD. Ce nouveau backend est écrit en Go et sera fourni sous forme de binaire avec la version officielle de TSBOARD.
Pourquoi avoir recréé le backend ?
- Le runtime Bun offre vraiment d’excellentes performances. Mais malgré sa présentation comme toolkit tout-en-un, sa gestion des paquets n’est pas encore au niveau de npm.
- À cause de cela, utiliser TSBOARD nécessitait deux runtimes : Node.js et Bun. C’était encombrant et peu pratique pour les utilisateurs.
- Même si le problème a depuis été corrigé, le fait qu’au début Bun ne fonctionne pas sur des CPU virtuels était critique, au point que moi, le développeur, je ne pouvais même pas le déployer sur d’autres serveurs.
- (Comme certains l’ont souligné) on peut bien sûr recourir à de l’orchestration, mais je voulais dépasser les limites inhérentes aux runtimes JS, notamment leur contrainte single-thread, et tirer parti de plusieurs threads.
- J’avais besoin de davantage de types. TypeScript seul ne suffisait pas à combler ce manque.
Pourquoi avoir choisi Go ?
- Le nouveau backend devait 1) être compilé, 2) gérer la mémoire automatiquement si possible, et 3) ne pas exiger l’installation d’un runtime supplémentaire.
- Après avoir hésité entre Rust, Kotlin, Python, PHP et Go, j’ai choisi Go, qui remplissait ces trois conditions et constituait en plus une première pour moi. (Désolé PHP)
- Ce qui m’a le plus séduit dans Go, c’est sa simplicité, ainsi que ses similarités avec TypeScript. Surtout, j’ai pensé que c’était un meilleur choix que les autres alternatives en matière de gestion de la concurrence et de la mémoire.
Go, à l’usage, ça donne quoi ?
- J’ai réalisé que Go confirmait lui aussi qu’aucun langage n’a que des qualités.
if err != nil { }est indispensable, certes, mais vraiment pénible. Il m’arrive souvent de regrettertry catch finally. - C’est probablement lié à un problème de
go-mysql-driver, mais dans un environnement de développement réel avec un goulot d’étranglement sur les I/O de base de données, ce n’était pas si rapide. (Voir le post publié ici sur GeekNews : https://fr.news.hada.io/topic?id=18048) - L’application implicite des interfaces me paraît encore un peu étrange. Ils ne voulaient vraiment pas de mots-clés comme
implementsouextends? - J’ai été content de retrouver les pointeurs. Surtout parce qu’on n’a pas à se soucier du moment où la mémoire est libérée !
- Les différents types, les structs simples mais puissantes, et les slices sont formidables. Le faible nombre de mots-clés permet d’apprendre vite et de s’en servir rapidement, c’est ce que j’apprécie le plus.
- Pouvoir utiliser comme par magie des threads légers avec le mot-clé
go...! Quel bonheur !
Retour d’expérience après être passé d’un backend basé sur un runtime JS à Go...?
- Une fois suffit largement pour ce genre de folie.
- J’ai fait différents tests en benchmarkant la partie DB I/O, et du point de vue des performances, il est en réalité difficile de ressentir une grande différence entre un runtime JS et un binaire Go. Par exemple, pour une bibliothèque d’images très utilisée en JS comme
sharp, on utilise de toute façon aussi la bibliothèquelibvips, et il n’existe pas d’application web sans DB I/O. - Malgré tout, même si j’en ai bavé, je pense que ce changement était le bon, et j’ai l’intention de continuer à n’utiliser que Go pour le backend à l’avenir.
- La consommation mémoire baisse vraiment de façon significative. Bien sûr, on pourrait optimiser davantage avec Rust, mais à ce niveau, c’est déjà largement satisfaisant en échange de l’usage d’un GC.
- La simplicité du langage est vraiment folle. Il y a peu de mots-clés à mémoriser, les patterns d’usage sont en grande partie établis, donc c’est facile à apprendre. (Bien l’utiliser, c’est une autre histoire.) J’ai particulièrement aimé la variété des types primitifs disponibles.
- Et surtout, le point le plus satisfaisant : une fois compilé, il suffit d’avoir le binaire pour que ça fonctionne. Je n’ai plus envie d’installer encore quelque chose juste pour lancer le backend et réexécuter le code avec.
Comment l’utiliser ?
- L’environnement Windows n’est malheureusement pas pris en charge. Il faut exécuter le binaire sous Linux/Mac.
- La bibliothèque
libvipsdoit être installée à l’avance sur votre serveur, car le binaire s’appuie sur ses fonctionnalités pour le traitement d’images. - Plus de détails sont expliqués dans le fichier
README.md.
Il reste encore beaucoup à améliorer, et j’attends toujours avec intérêt les avis des autres développeurs. J’en viens presque à m’en vouloir d’avoir été si hésitant lors de l’événement GeekNights. Les signalements de bugs, les propositions d’amélioration, ou même les points de vue originaux sont tous les bienvenus.
Ce mois de décembre est particulièrement éprouvant cette année, mais j’espère tout de même qu’un avenir un peu meilleur nous attend avec la nouvelle année. Merci d’avoir lu ce long texte. Pour finir, je partage ci-dessous le lien vers les notes de version de TSBOARD v1.0.0.
12 commentaires
Je l’ai découvert sur Damoang.
C’est un CMS prometteur. Merci.
J’ai aussi été surpris de voir qu’il y avait des personnes sur Damoang qui se souvenaient de moi. Haha, je ferai de mon mieux pour être à la hauteur de vos attentes ! 😊
C'est utile !
Merci pour votre commentaire, même s’il arrive un peu tard ! 😃
Il y a des avantages et des inconvénients, mais parmi les avantages, je trouve parfois appréciable le fait de pouvoir, sans modifier le code des bibliothèques standard ou externes, utiliser une implémentation créée par quelqu’un d’autre tout en traitant une partie de celle-ci comme une interface que j’ai moi-même définie. Un peu comme
FunctionalInterfaceen Java, ou comme si on appliquait le duck typing à un langage compilé. À l’inverse, avec une approche oùimplements/extendsdoivent être déclarés explicitement, si l’on veut rattacher quelque chose à une interface que l’on a créée, il faut implémenter un Adapter intermédiaire.Côté inconvénients, lorsqu’on ajoute, supprime ou modifie une méthode dans une interface, l’emplacement où les erreurs sont signalées diffère de celui des autres langages à typage statique, ce qui est un peu gênant.
Ah, je vois ! Il y avait donc un avantage auquel je n’avais même pas pensé. Heureusement, les messages d’erreur, c’était
gopls, je crois ? L’extension Go de VSCode les repérait très bien, donc j’ai pu trouver rapidement ce que j’avais oublié ou mal implémenté. Quand je serai un peu plus habitué, je pense que moi aussi j’arriverai un jour à mieux l’utiliser. Haha, merci pour vos explications en commentaire ! Je vous souhaite une très bonne année~ !Beau travail ! Je vais aussi le déployer sur mon serveur de test ! Je vous souhaite beaucoup de réussite pour la nouvelle année 2025 !
Merci ! N’hésitez pas à l’essayer, et si jamais cela ne fonctionne pas bien ou si vous avez la moindre question, faites-le nous savoir à tout moment ! Bonne année ~ !
Je vous soutiens~ 👍🏻
Merci pour votre soutien !!! Bonne année à tous~ !
Je vous soutiens !
Merci !!! Bonne année !!