Journal Je me lance dans un petit projet en Rust

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes : aucune
5
22
mar.
2026

Cher journal,

Je me suis mis à expérimenter un peu avec Rust dans l'optique de faire un petit serveur business pour Bim!. Peut-être te souviens-tu que j'avais envisagé ce langage pour le jeu au début de son développement ? À l'époque j'avais considéré que la marche était trop haute vis-à-vis de la taille du projet et je m'étais rabattu sur des outils éprouvés. Je pense toujours que ça aurait été un mauvais choix, mais par contre pour la partie business du serveur, qui devrait être relativement petite, cela me semble une bonne opportunité pour m'y mettre.

Pour me mettre dans le bain j'ai simplement développé une petite preuve de concept. J'aimerais bien que tu me donnes ton avis dessus histoire que je ne commence pas déjà à prendre de mauvaises habitudes et que je ne finisse pas dans un mur :) Le projet est tout petit, il ne fait que 600 lignes. Il y a quelques questions que je me pose dans les commentaires du code.

Il y a plein d'inconnues pour moi sur ce projet, notamment Rust, mais aussi la programmation asynchrone (je suis habitué à la concurrence et aux threads, mais je n'ai jamais utilisé de coroutines ou de trucs dans le genre), ainsi que les bases de données (je n'y ai pas touché depuis l'université).

Le but du projet est donc de construire une sorte de serveur business pour Bim! (et apprendre Rust au passage). Il devra gérer des choses telle que:

  • Fournir la config à l'app cliente.
  • Stocker l'inventaire des joueurs.
  • Garder un journal des transactions (quand et où le joueur gagne ou dépense ses pièces).
  • Autoriser des modifs via un compte administrateur.
  • Certainement plus.

Il semblerait que j'aurais pu utiliser une solution clé en main telle que Nakama pour cela, mais alors je n'apprendrai pas grand chose (et j'aime aussi être relativement indépendant).

J'ai lu un peu au sujet de CRUD et si je comprends bien c'est ce que je veux faire. Pour les services web j'ai considéré Rocket, Loco, et Axum. J'ai commencé avec Rocket mais je suis revenu en arrière et au final j'utilise Axum. Pour la partie business j'ai envisagé Diesel, tokio-postgres, postgres, et SQLx. J'étais parti initialement sur Diesel, puis SQLX, mais au final j'ai pris tokio-postgres. Puis j'ai changé à nouveau pour deadpool-postgres.

J'ai laissé tomber Rocket parce que je n'arrivais pas à prendre le projet au sérieux. Le vocabulaire est inutilement complexe (mount, launch, fairing, ignite, liftoff…), trop métaphorique. C'est un service web, pas une fusée. Puis à la première exécution il a vomi un arc-en-ciel plein d'émojis dans mon terminal, donc j'ai arrêté. Nous ne sommes pas sur la même longueur d'onde. De son côté, Loco est, tel qu'indiqué sur son site, comme Ruby on Rails, mais pour Rust. Malheureusement mes expériences passées avec RoR étaient plutôt déplaisantes :) Trop de magie et trop de questions telles que « ai-je vraiment besoin de cela ? » ou encore « ai-je vraiment besoin de ne pas comprendre ? ». De plus ça semble bien complexe pour mes besoins. Axum est très simple, pas de fantaisies. Ça demande certainement d'écrire plus de code mais ça ne me dérange pas, et je peux suivre ce qu'il se passe.

J'ai laissé tomber Diesel pour plein de raisons. D'une part je ne voyais pas pourquoi j'aurais envie de mapper mes structs sur les tables. N'est-ce pas un fort couplage qui va rendre le logiciel trop rigide ? D'un autre côté ça a l'air parfois pratique. Dans les exemples j'ai vu qu'il y avait une description de la base dans un fichier schema.rs, mais il y a aussi la structure correspondante dans un autre fichier (model.rs). N'est-ce pas galère à maintenir ? Ensuite il y a le fait que Diesel ait besoin d'un outil spécifique en ligne de commande pour s'intégrer au projet. Enfin, il peut vérifier la syntaxe des instructions SQL à la compilation mais si j'ai bien compris il a besoin d'un serveur de bases de données pour cela. Est-ce que ça vaut vraiment le coup ? Je m'attends à ce que toutes les requêtes soient exécutées durant les tests de toute façon.

J'ai à peine testé SQLx principalement parce que ça semble être dans le même genre que Diesel.

Enfin, tokio-postgres avait l'air chouette mais je n'ai pas réussi à partager l'instance du Client avec plusieurs services web (le borrow checker s'est mis en travers), puis je me suis demandé si la connexion allait rester valide pour toujours avec le serveur de bases de données tournant sur le même hôte. Je n'étais pas sûr (et je pense que la réponse est plutôt « probablement pas ») donc j'ai migré vers deadpool-postgres qui m'a permis de partager la pool avec plusieurs services et qui simplifie la gestion des connexions.

Au sujet de Rust lui-même, je suis plutôt satisfait du langage. Néanmoins le fait que Cargo télécharge la moitié d'Internet pour mon petit projet est décevant. Aucun doute que je vais finir par télécharger une dépendance corrompue, mais j'imagine que c'est comme ça et puis c'est tout. Sur le langage, ce serait mieux si je pouvais supprimer quelques await, quelques ?, et la plupart des map_err. Je veux que la plupart des erreurs terminent en code d'erreur HTTP 500 de toute façon. Donc si tu as des suggestions pour simplifier tout ça, elles sont bienvenues :)

  • # quelques feedbacks rapide

    Posté par  . Évalué à 2 (+1/-0).

    (re)Bienvenu dans le monde merveilleux de Rust ^
    - Axum est un standard, donc probablement un bon choix
    - Diesel est un ORM alors que ce n'est pas le cas d'SQLx
    - si tu souhaites ne supporter que Postgres, tokio-postgres semble être le bon choix.
    - même si ton serveur est très simple, c'est quand même un backend http avec base de donnée, ça implique donc une complexité non négligeable, donc c'est normal que tu tires beaucoup de crates. Si tu veux te limiter au strict minimum, importe les crates en mode "no-default-features" et active seulement les features dont tu as besoin.
    - les ? et map_err avec une architecture de code qui prend en compte les possibilités d'erreur et une bonne gestion c'est un atout, mais avant d'avoir trouvé la bonne formule on peut se retrouver à lutter contre gestion des erreurs.
    - pour la gestion des erreurs, utilise thiserror plutôt que d'implémenter les traits à la main 😉
    - https://blessed.rs peut aider à choisir une crate

    • [^] # Re: quelques feedbacks rapide

      Posté par  (site web personnel) . Évalué à 3 (+1/-0).

      Merci pour les retours :)

      pour la gestion des erreurs, utilise thiserror plutôt que d'implémenter les traits à la main 😉

      Ah bah c'est de là que venait le #[from] que j'ai tenté d'utiliser ! J'avais croisé ça sur StackOverflow ou un blog, sans savoir d'où ça venait.

      Blessed liste un certain anyhow qui a l'air bien tentant aussi.

      • [^] # Re: quelques feedbacks rapide

        Posté par  . Évalué à 3 (+2/-0). Dernière modification le 22 mars 2026 à 22:38.

        Oui anyhow peut être intéressant aussi, mais j'ai tendance à en réserver l'usage au retour de la fonction main.

        D'ailleurs j'ai pas précisé, mais ce qui est cool avec thiserror c'est qu'il utilise le champ source pour faire des stacks d'erreurs, que anyhow affiche joliment en cas d'erreur qui remonte jusqu'au return du main.

        J'en profite, attention ce n'est pas forcément une bonne idée de trop customiser le formatage, ça permet de moins changer les habitudes de lecture de code, mais ça fait qu'on s'habitue moins au standard de Rust, et donc rend plus difficile la lecture du code Rust externe comme inspiration ou des crates utilisé.

        En venant de C++, au départ ça fait bizarre de ne pas mettre les returns en fin de fonction, mais une fois l'habitude prise, c'est mieux d'éviter et de garder pour les early returns

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.