Technologie

Développement Node.js pour des backends en TypeScript

Node.js permet aux équipes produit d'utiliser un seul langage, TypeScript, sur le front-end comme sur le backend. Nous l'utilisons pour le développement Node.js d'API, de backends-for-frontends, de fonctionnalités temps réel et de fonctions serverless, et nous sommes transparents sur les cas où un backend sur la JVM est un meilleur choix.

Là où Node.js excelle

Node.js exécute du JavaScript sur une boucle d'événements avec des entrées/sorties non bloquantes, ce qui le rend efficace pour les services qui passent l'essentiel de leur temps à attendre des bases de données, d'autres API ou des connexions réseau. C'est un choix naturel pour les API qui servent des clients web et mobiles, les fonctionnalités temps réel via WebSockets et les services légers qui relient d'autres systèmes entre eux.

Son principal avantage pratique est le partage de TypeScript sur toute la stack. Types, schémas de validation et clients d'API peuvent être partagés entre un front-end React et le backend, ce qui élimine toute une catégorie de bugs d'intégration et permet aux petites équipes d'avancer plus vite.

Node.js ou Java : une comparaison honnête

Node.js est mal adapté aux traitements gourmands en CPU, comme les transformations de données volumineuses, le traitement d'images ou les calculs complexes, car un calcul long bloque la boucle d'événements pour toutes les requêtes. Les worker threads aident, mais à ce stade un service sur la JVM ou en Go est souvent plus simple.

Pour les grands domaines à la logique transactionnelle complexe et à longue durée de vie, nous recommandons souvent plutôt Java avec Spring Boot : le système de types, l'outillage et le profilage à l'exécution y sont plus matures pour ce type de système. Beaucoup d'architectures combinent les deux, avec Node.js pour les backends-for-frontends et Java pour les services du cœur de domaine.

Comment nous développons des backends Node.js

Nous écrivons nos services Node.js en TypeScript strict, sur les versions LTS actuelles. Pour les applications d'envergure, nous utilisons NestJS, dont les modules et l'injection de dépendances offrent une structure claire qui tient la route entre plusieurs équipes ; pour les petits services sensibles aux performances, nous utilisons Fastify. Les entrées sont validées en périphérie avec des schémas, qui génèrent aussi la documentation OpenAPI.

L'accès aux données passe par des query builders typés ou des ORM comme Prisma ou Drizzle, avec des migrations explicites. Les traitements longs ou rejouables sont déportés dans des files de messages plutôt que dans les gestionnaires de requêtes. Chaque service est livré avec des logs structurés, des health checks, du tracing OpenTelemetry et un arrêt propre (graceful shutdown) pour se comporter correctement en conteneur.

  • TypeScript strict, ESLint et vérification des types imposés dans la CI
  • Tests unitaires avec Vitest, tests d'API contre de vraies bases de données avec Testcontainers
  • Tâches de fond avec BullMQ ou des files cloud natives plutôt que des timers dans le processus
  • Audit des dépendances et hygiène des lockfiles pour réduire les risques liés à la chaîne d'approvisionnement logicielle

Backends-for-frontends et serverless

Un backend-for-frontend (BFF) est un service léger taillé pour un client précis, comme une application web ou mobile. Il agrège les appels aux services sous-jacents, gère les questions de session et d'authentification et renvoie exactement les données dont l'interface a besoin. Node.js est bien adapté à ce rôle, car il peut partager ses types directement avec le client.

Pour les charges irrégulières ou orientées événements, nous déployons Node.js sur AWS Lambda ou Azure Functions, en limitant les cold starts grâce à des bundles légers et un minimum de dépendances. L'infrastructure est définie en code dans le cadre de nos services cloud et DevOps.

Reprendre une base de code Node.js existante

Les projets Node.js vieillissent vite : paquets non maintenus, code de l'époque des callbacks, types absents et gestion des erreurs incohérente. Nous commençons par un audit des dépendances et de la sécurité, ajoutons des tests autour des endpoints critiques, puis migrons progressivement vers TypeScript et les versions LTS actuelles de Node.js. Si le service a dépassé sa conception d'origine, nous abordons sa restructuration dans le cadre de notre offre de développement backend et API.

Cas d'usage

Ce que nous construisons avec Node.js

  • 01

    API pour applications web et mobiles

    Des API REST et GraphQL en TypeScript, qui partagent types et validation avec les applications clientes qui les consomment.

  • 02

    Backends-for-frontends

    Des services dédiés à un client qui agrègent plusieurs backends et gardent le code front-end simple et rapide.

  • 03

    Fonctionnalités temps réel

    Notifications, collaboration et tableaux de bord en direct via WebSockets ou server-sent events.

  • 04

    Fonctions serverless et orientées événements

    Des handlers Lambda ou Azure Functions pour les webhooks, les tâches planifiées et le traitement de files, définis en code.

Écosystème

Les outils que nous associons à Node.js

  • Node.js LTS
  • TypeScript
  • NestJS
  • Fastify
  • Express
  • Prisma
  • Drizzle ORM
  • BullMQ
  • Vitest
  • OpenTelemetry
  • AWS Lambda

FAQ

Questions fréquentes

Node.js est-il adapté aux applications d'entreprise ?

Oui, pour les bonnes charges de travail : API à forte intensité d'entrées/sorties, BFF et services d'intégration. Avec TypeScript strict, un framework structurant comme NestJS et des tests sérieux, une base de code Node.js peut être aussi maintenable que n'importe quelle autre. Pour les traitements gourmands en CPU ou les domaines transactionnels très complexes, nous recommandons généralement un service sur la JVM en complément.

Faut-il choisir NestJS, Fastify ou Express ?

NestJS convient aux applications d'envergure et aux équipes qui tirent profit d'une structure cohérente et prescriptive. Fastify est un bon choix pour les petits services rapides. Express reste répandu dans les bases de code existantes, et nous le maintenons, mais nous le choisissons rarement pour de nouveaux projets.

Pouvez-vous migrer notre backend JavaScript vers TypeScript ?

Oui. Nous activons TypeScript aux côtés du JavaScript existant et convertissons la base de code fichier par fichier, en commençant par les modules les plus critiques, pour que les livraisons continuent pendant la migration.

Des services Node.js et Java peuvent-ils fonctionner ensemble dans un même système ?

Oui, et c'est un schéma courant. Les services communiquent via des API bien définies ou des brokers de messages, ce qui permet à chacun d'utiliser l'environnement d'exécution qui lui convient. Découvrez notre approche sur la page développement Java.

Un projet en tête ?

Construisons ensemble quelque chose d'exceptionnel.

Dites-nous où vous en êtes et où vous voulez aller. Nous vous répondons sous un jour ouvré avec des prochaines étapes honnêtes, quitte à vous orienter ailleurs.