3 points par GN⁺ 2024-10-07 | 1 commentaires | Partager sur WhatsApp
  • Même pour créer une petite application web en Rust, il manque une expérience intégrée à la Django ; il faut donc assembler soi-même le routage, la connexion, la base de données et les fonctions d’administration
  • Le framework nécessaire devrait regrouper par défaut le routage/les handlers, les templates, le service de fichiers statiques, la connexion, les autorisations, l’interface DB, les outils d’administration, les WebSockets et le hot reloading
  • Il existe des frameworks minimalistes comme actix-web et axum, ainsi que des frameworks SPA comme Dioxus, Leptos et Yew, mais aucun ne prend en charge à lui seul l’assemblage complet d’une application web
  • Les templates de démarrage réduisent la configuration initiale, mais une fois le projet divergé, la fusion des changements et les mises à jour de bibliothèques deviennent une charge de maintenance
  • newt vise un toolkit web qui assemble des composants existants de manière opinionated, avec pour objectif de permettre de démarrer une petite application web en quelques minutes plutôt qu’en plusieurs jours

Ce qui manque au développement web Rust : un point de départ intégré

  • Même pour un petit projet web en Rust, il faut bien plus de travail de raccord initial qu’avec Django ou un framework comparable
  • L’approche courante dans la communauté Rust consiste plutôt à relier soi-même les briques nécessaires
    • Même Are We Web Yet? indique que, pour le développement web en Rust, il faut généralement faire l’assemblage soi-même et prévoir un travail de configuration supplémentaire au départ
  • Ce travail supplémentaire n’est pas simplement « un peu plus » : il y a en pratique beaucoup d’éléments à traiter avant même de démarrer le projet
  • Disposer d’un framework web intégré rendrait Rust plus facile à proposer pour des applications web
    • Parmi les avantages de Rust sont cités le système de types, les performances et les pauses café pendant la compilation

Les briques de base nécessaires à presque toutes les applications web

  • Routage / handlers

    • Les requêtes entrantes doivent être envoyées vers le bon handler
    • Il faut gérer les paramètres de chemin, idéalement avec des informations de type
    • La gestion des paramètres de requête et des formulaires est aussi souhaitable
  • Templates

    • Il faut générer du HTML, et parfois aussi du JSON ou du XML
    • Une logique de base est nécessaire : conditions, match/switch, boucles
  • Service de fichiers statiques

    • Il faut servir des ressources comme le CSS
    • Cela peut être géré par un serveur séparé, mais pour le développement local et les petits déploiements, l’inclure dans le même serveur web est pratique
  • Connexion

    • Une application est généralement multi-utilisateur ou déployée sur un réseau public, donc la connexion est presque toujours nécessaire
    • Comme il est pénible de la recâbler à chaque fois, elle devrait être facile à utiliser dès le départ
    • Elle doit rester personnalisable et désactivable
  • Autorisations

    • Dans un système avec plusieurs utilisateurs, les données accessibles et les rôles diffèrent
    • Le simple modèle check(user, object, action) permet déjà d’aller assez loin
  • Interface DB

    • Il faut un moyen de stocker les données de l’application
    • Une approche proche d’un ORM peut être utile, mais une solution plus légère peut aussi convenir
    • C’est un composant de base, car il sert à la connexion, aux autorisations et aux outils d’administration
  • Outils d’administration

    • Lorsqu’on configure l’application en local ou en production, il faut au minimum initialiser un utilisateur ou certaines données
    • Avoir quelques tâches d’administration courantes intégrées rend l’expérience plus fluide
  • WebSockets

    • Ils permettent de créer des fonctions qui poussent les données aux utilisateurs connectés de façon plus proche du temps réel
  • Hot reloading

    • Les changements de code ou de templates doivent être reflétés aussi vite que possible, ce qui est crucial pour l’expérience développeur

Les fonctions de renfort nécessaires aux projets qui durent

  • Tâches en arrière-plan

    • Des fonctions à exécuter selon un calendrier finissent par apparaître, donc une approche cohérente facilite le développement
  • Monitoring / observabilité

    • C’est nécessaire sauf pour les systèmes les plus petits et les moins critiques
    • Et cela aide énormément au moment où cela devient vraiment indispensable
  • Cache

    • Il existe de nombreuses façons de l’implémenter, toutes ajoutent de la complexité, et le gain de performance dépend du contexte
    • Une approche au niveau du framework serait bienvenue, mais l’utilisateur peut aussi le gérer lui-même
  • E-mails et notifications

    • S’il y a une fonctionnalité de connexion, l’e-mail devient pratiquement nécessaire pour la réinitialisation de mot de passe
    • Les autres notifications peuvent être ajoutées plus tard si besoin
  • Outils de déploiement

    • Il est utile d’avoir une manière cohérente de déployer vers une cible donnée
    • Même un Dockerfile généré automatiquement pour l’hébergeur choisi serait déjà utile
  • Bundling CSS/JS

    • Il serait bien que l’outil web reconnaisse le CSS et le JS et les intègre naturellement
    • Il n’est pas certain que cela doive absolument être intégré

Les vides laissés par l’écosystème web Rust actuel

  • Rust dispose déjà de nombreux outils pour le développement web, mais aucun ne vise l’expérience intégrée recherchée ici
  • Frameworks web minimalistes

    • actix-web et axum sont plus proches de petits frameworks comme Flask ou Sinatra
    • Ils offrent une bonne expérience de développement web en tirant parti du système de types de Rust, mais fournissent très peu de fonctionnalités au-delà des handlers
    • Même si la plupart des projets peuvent être construits avec ces frameworks minimalistes, devoir reconnecter toutes les fonctions nécessaires à chaque fois reste pénible
  • Frameworks SPA

    • Dioxus, Leptos et Yew couvrent le cas où Rust est utilisé à la fois côté back-end et front-end, avec WebAssembly pour le rendu front-end
    • L’expérience de création de digital vigil avec Yew a été agréable, mais il n’est pas certain qu’il donnerait envie d’être utilisé en production réelle
    • Ces frameworks sont eux aussi excellents pour leur objectif propre, mais demandent encore beaucoup de travail d’assemblage
  • Assemblages de bibliothèques séparées

    • Il existe de nombreuses bibliothèques pour les templates, la connexion, les autorisations et les WebSockets
    • Certains projets et exemples intègrent quelques composants, mais il est difficile d’en trouver qui intègrent toutes les pièces utilisées
    • Comme l’écosystème évolue vite, certains exemples peuvent déjà être obsolètes
    • « Il suffit de brancher » revient au final à devoir étudier le fonctionnement de chaque bibliothèque et à le comprendre suffisamment bien

La maintenance que les templates de démarrage ne résolvent pas

  • L’approche existante consiste en général à choisir un framework de base comme actix-web ou axum, puis à ajouter les pièces nécessaires et à les relier soi-même
  • Les templates de démarrage peuvent réduire la douleur initiale, mais la charge de maintenance demeure
    • Il faut maintenir les bibliothèques à jour
    • Il faut aussi faire face aux changements incompatibles (breaking changes)
    • Une fois le projet éloigné du template, il devient difficile de refusionner les modifications du template
  • Quand on gère plusieurs projets, au lieu de mettre à jour un seul framework, il faut mettre à jour n frameworks personnalisés distincts
  • Il vaut mieux qu’un framework web complet fournisse des indications de migration entre versions
    • Des changements incompatibles peuvent toujours survenir, mais ils peuvent être documentés
    • Cela réduit les situations où des problèmes viennent d’un changement d’interaction entre deux composants qui n’ont pas été conçus en sachant qu’ils seraient intégrés ensemble

Le toolkit web que vise newt

  • Le framework web Rust idéal devrait offrir les fonctionnalités listées plus haut, ainsi qu’une bonne documentation, un journal des changements, une gestion de versions soignée, une prise en charge des changements incompatibles et une communauté
  • Un tel outil n’existe pas aujourd’hui, et il n’est même pas certain que quelqu’un d’autre soit en train de le construire
  • L’outil en cours de développement ressemble moins à un framework qu’à un toolkit web assemblant des briques existantes de manière opinionated
  • Ce toolkit s’appelle nicole's web toolkit, abrégé en newt
    • Il est publié dans un public repository
    • Il n’est pas encore dans un état utilisable, et les derniers changements n’ont pas encore été poussés
    • Il n’est pas encore prêt à recevoir des contributions
  • L’objectif de newt est que, lors de la création d’une nouvelle petite application web, on puisse commencer le vrai travail sur le projet en quelques minutes au lieu de passer plusieurs jours à faire du câblage
  • Certains composants pourraient aussi être créés from scratch selon les besoins
    • Cela peut être plus simple ou mieux s’intégrer à l’ensemble
  • L’écosystème Rust a besoin d’un état sain où plusieurs toolkits de ce type coexistent, et l’auteur espère voir apparaître d’autres outils également

1 commentaires

 
GN⁺ 2024-10-07
Avis sur Hacker News
  • Je suis surpris que Rocket (https://rocket.rs/) ne figure pas parmi les frameworks listés par l’auteur
    Je ne l’ai pas utilisé moi-même et je préfère axum/actix-web, moins prescriptifs, mais si j’ai bien compris, l’objectif de Rocket est beaucoup plus proche du framework batteries included que souhaite l’auteur, et c’est déjà un projet assez ancien

    • Rocket a été l’un des premiers frameworks Rust à pousser une bonne expérience développeur au moyen de macros procédurales, mais il semble avoir perdu beaucoup de popularité dans plusieurs pans de la communauté
      Pendant très longtemps, sa compilation nécessitait nightly Rust, ce qui était un gros motif d’exclusion pour les gens qui voulaient utiliser le framework en production
      Il est aussi resté bloqué pendant environ 2 ans au stade de release candidate 0.5.0, tandis que la dernière version stable était très en retard par rapport aux autres frameworks web Rust. Elle nécessitait nightly et ne prenait pas encore en charge l’asynchrone
      Maintenant que le cap de la 0.5 est passé, la situation s’est peut-être améliorée, mais l’historique de développement de Rocket donne envie d’hésiter à l’utiliser face à des alternatives comme Axum
  • Il en existe un : Poem[1]
    L’auteur mentionne Flask, mais à lire la section « ce qu’il faut », il est difficile de dire que Flask répondrait à ces exigences. Je déteste vraiment Django, mais pour ce type de besoins, ce qui se rapproche le plus de ce que décrit l’auteur est Django
    De ce point de vue, Poem n’est pas non plus un très bon candidat. Globalement, Poem ressemble pas mal à FastAPI, et c’est plutôt un compliment. J’ai utilisé cinq ou six frameworks web Rust, et la plupart obligent à manipuler beaucoup de boilerplate lors de la configuration initiale. Si l’on veut obtenir rapidement un résultat, c’est un problème ; sur ce point, Poem convient bien
    actix offre de très bonnes performances, mais si l’objectif n’est pas d’avoir des réponses en moins de 30 ms, il y a peu de raisons de regarder actix au départ. Si vous avez besoin de quelque chose à la Pydantic, il existe aussi une crate qui en fait une partie : https://crates.io/crates/poem-openapi
    [1] https://github.com/poem-web/poem

    • Pas seulement Django : Rails, ASP .NET Core et beaucoup d’autres frameworks web complets avec batteries incluses entrent aussi dans cette catégorie
      Le point clé, c’est qu’il s’agit d’un « framework »
  • F# vaut aussi le détour
    On y trouve presque tous les jeux de système de types souhaités, ainsi que les outils et commodités nécessaires. Le gros inconvénient, c’est que l’asynchrone et la gestion mémoire n’engloutissent pas autant de temps qu’en Rust, ce qui crée le risque de finir par résoudre réellement les besoins métier
    Cela dit, une partie des interactions avec Microsoft pourra peut-être combler ce vide

    • F# n’a-t-il pas besoin de la machine virtuelle .NET ? La plupart des gens que je connais qui choisissent Rust apprécient le fait que le code soit toujours compilé en natif, sa prévisibilité, et l’absence d’aléas liés aux pauses de récupération du garbage collector
    • Je me demande toujours si je devrais essayer F#
      Comment se compare-t-il à OCaml ou Haskell ?
  • Opinion peut-être impopulaire : Rust est un langage système, et faire du web en Rust est un gaspillage d’efforts
    Il existe des langages et des écosystèmes bien meilleurs pour cet usage

    • Contre-argument : développer des services web en Rust est aussi facile qu’en Go ou Java, tout en bénéficiant d’un excellent système de types (types somme !), d’un excellent gestionnaire de paquets et de très bonnes performances
      Comme en Java, on peut faire de l’injection de dépendances en Rust pour partager des pools de connexions, et les tâches d’arrière-plan basées sur des threads s’écrivent aussi très simplement
      Google a dit dans une présentation récente avoir mesuré que les développeurs Rust n’étaient pas moins efficaces ni moins productifs que les développeurs Go [1]
      Rust est un excellent langage, et il n’y a absolument aucune raison de le limiter à la programmation système. Il peut faire beaucoup plus
      [1] https://www.ardanlabs.com/news/2024/rust-at-google/
    • J’utilise toujours C/C++ pour les serveurs web
      C’est léger, cela permet d’appeler facilement et rapidement du code C/C++ et bas niveau, et cela donne beaucoup de contrôle sur le réseau. Sans devoir apprendre un langage spécialisé pour les applications comme PHP, ni des fichiers de configuration nginx/apache, on peut faire presque n’importe quoi de façon générale et intuitive
      J’aimerais bien qu’il existe une alternative Rust à quelque chose comme libmicrohttpd, et si elle existait, je pense que je l’utiliserais
    • Je suis presque entièrement d’accord, mais je tiens à souligner que l’intersection entre programmation système et programmation web n’est pas vide
      Il en va de même pour l’intersection entre programmation embarquée et programmation web
      Cela dit, si des options comme Django, .Net ou Go sont possibles, Rust est en général probablement un mauvais choix
    • C’est un investissement dans l’efficacité énergétique
    • Cela se défend sur des systèmes où la mémoire ou le CPU sont plus contraints que d’habitude
      Un framework web compilé statiquement peut facilement n’utiliser que 1/10 à 1/100 de la mémoire/CPU de solutions comme Rails, Django ou Flask
  • Python a Django, C# a ASP .NET Core, Ruby a Rails
    Si l’on veut vraiment faire fortement progresser Rust dans le développement web, il faut créer une solution complète
    Rocket est peut-être ce qui s’en rapproche le plus, mais il n’est pas aussi batteries included que les frameworks mentionnés plus haut

  • Ce que cherche l’auteur, c’est la version Rust d’ASP.NET Core, et il n’y a aucun problème à cela
    Certains aiment avoir du choix et assembler eux-mêmes les pièces, mais dans beaucoup d’environnements, il est bien plus productif que les choix soient présélectionnés pour vous
    Les réactions du type « et si je veux un autre X ? Y pourrait être meilleur de Z % ! » sont courantes, mais elles passent à côté de l’immense valeur de l’intégration. Des bibliothèques prises individuellement peuvent être les meilleures, mais si elles ne s’emboîtent pas proprement, l’ensemble peut devenir un tas d’ordures
    Si j’aime programmer avec ASP.NET 8, c’est aussi parce que je n’ai pas du tout à me demander si le système de templates va bien s’intégrer avec l’authentification, l’injection, le routage, etc.

  • Aucune mention de loco-rs, poem, rocket ? Il y a déjà pas mal de projets qui visent une expérience batteries included
    Ce qui distingue ces projets de frameworks comme leptos, c’est qu’ils ont un CLI qui vous guide. C’est aussi ce que j’aime dans Symfony, et c’est là que se situe, selon moi, la partie « paresseuse »

  • Il y a https://shuttle.rs
    Ce n’est pas seulement un framework, mais aussi un outil qui génère le boilerplate web autour ; selon mes critères, c’est donc suffisamment paresseux.

  • Cet article aborde plusieurs points différents en même temps ; idéalement, chacun devrait être traité séparément
    Avec du pattern matching, on n’a pas forcément besoin d’un routeur. Il suffit de découper l’URL et de faire correspondre les variables statiques/dynamiques selon les besoins.
    L’authentification, dans n’importe quel langage, se fait généralement soit en la développant soi-même, soit en utilisant un SaaS comme Firebase/Auth0 ; ce n’est donc pas nécessairement un problème de langage ou de framework.
    Les outils CSS/JS ne conviennent pas bien à de nombreux frameworks frontend Rust comme Dominator. Dominator est écrit en Rust, pas en JS, et a sa propre approche du styling, par exemple en attachant des styles à des signaux pour qu’ils changent en temps réel.
    Je comprends ce que veut dire l’auteur. En pratique, j’ai moi-même fait plusieurs fois le tour des solutions pour résoudre différents points cités dans l’article, et ça a été pénible. Par exemple, https://github.com/dakom/dominator-workers-fluent-auth gère beaucoup des tâches mentionnées ici au-dessus du framework Cloudflare Workers, et ajoute aussi un souhait supplémentaire : la localisation basée sur Fluent.
    Ce serait bien d’avoir un framework complet batteries incluses qui fasse tout, mais beaucoup de projets réels voudront remettre en cause ce genre de décisions prescriptives et prendre la voie d’une implémentation maison. Rust est déjà suffisamment mature aussi pour le web frontend, et si l’on sait où regarder, on peut tout gérer avec wasm-bindgen et autres.

    • Dire qu’« avec du pattern matching, on n’a pas besoin de routeur » est insuffisant
      Un framework web fournit beaucoup plus de choses : redirections d’URL, gestion de la barre oblique finale, gestion des URL sensibles à la casse, correspondances par expressions régulières complexes, etc.
      Dire que « l’authentification, dans n’importe quel langage, se fait généralement soit soi-même, soit via un SaaS » est faux. Django, Laravel, Rails et les langages/frameworks batteries incluses offrent une très bonne gestion de l’authentification. Personnellement, je pense que pour 90 % des organisations, confier l’authentification à un prestataire externe est une énorme erreur.
      Le fait qu’un développeur web expérimenté puisse mettre en ligne en une journée dix CRUD de base sans gérer de complexité inutile est un avantage vraiment énorme pour les petites entreprises.
  • Si cet article avait porté sur C++ plutôt que sur Rust, est-ce que les mêmes remarques auraient globalement tenu ?
    C’est un langage système à forte barrière d’entrée, avec des temps de compilation, et il est irréaliste d’attendre d’un langage largement utilisé depuis moins de dix ans qu’il rivalise avec quelque chose comme Rails en matière d’accessibilité.