Conventions backend
Vue d'ensemble
Cette page décrit les conventions utilisées pour structurer les services backend NestJS dans le monorepo Feelbat.
L'objectif est de garder des services lisibles, maintenables et correctement séparés par domaine métier.
Objectif
À la fin de ce guide, vous comprendrez :
- La responsabilité d'un service backend.
- La structure standard d'un service NestJS.
- Comprendre la responsabilité de chaque couche.
- Savoir où placer le code dans un service.
Responsabilité d'un service
Chaque service backend doit gérer un domaine ou une feature clairement délimitée.
Un service ne doit pas prendre en charge des responsabilités qui appartiennent à un autre domaine.
Par exemple, un service de configuration ne doit pas être responsable de la mise à jour des capteurs.
Warning
Si un service commence à modifier directement des concepts métier appartenant à un autre domaine, c'est probablement un signe que la responsabilité du service est mal définie.
Un service peut communiquer avec d'autres domaines via :
- des APIs exposées par d'autres services ;
- des événements Kafka ;
- des ports applicatifs ;
- des contrats explicites.
Mais il ne doit pas devenir propriétaire de leur logique métier.
Structure standard
Chaque service backend suit la structure suivante :
src/
├── app/
├── cli/
├── domain/
├── infra/
├── interfaces/
├── shared/
├── app.module.ts
├── env.d.ts
└── main.ts
app/
Le dossier app contient la couche applicative du service.
Cette couche orchestre les cas d'utilisation du domaine.
Elle contient notamment :
app/
├── services/
└── ports/
Le dossier app regroupe généralement :
- les services applicatifs ;
- les ports ;
- les DTO d'entrée et de sortie ;
- les mappers applicatifs.
Cette page ne détaille pas le rôle de ces éléments. Consultez la section Architecture pour comprendre leur fonctionnement.
domain/
Le dossier domain contient le coeur métier du service.
Il regroupe l'ensemble des concepts métier propres au domaine.
👉 Voir : Architecture → Domain-Driven Design.
infra/
Le dossier infra contient les implémentations techniques utilisées par le service.
Elle regroupe les implémentations techniques du service (ORM, Kafka, clients externes, etc.).
👉 Voir : Architecture → Ports & Adapters.
interfaces/
Le dossier interfaces contient les interfaces d'entrée du service.
Elle contient les interfaces exposées par le service (GraphQL, HTTP, CLI, etc.), ainsi que les DTO et mappers spécifiques à ces interfaces.
👉 Voir : Architecture → Mappers.
cli/
Le dossier cli contient les commandes exposées par un service lorsque celui-ci propose une interface en ligne de commande.
Chaque fichier doit représenter une commande claire.
Exemple :
cli/
├── seed.command.ts
└── reindex.command.ts
Toutes les commandes CLI doivent appeler la couche applicative au lieu de manipuler directement l'infrastructure.
shared/
Le dossier shared contient le code utilitaire interne au service.
Exemples :
- validation des variables d'environnement ;
- helpers locaux ;
- constantes internes ;
- utilitaires spécifiques au service.
Warning
Le dossier shared d'un service n'est pas une bibliothèque globale.
Si du code est partagé entre plusieurs services, il doit être déplacé dans libs/feelbat.
Flux de dépendances
flowchart TD
Interfaces[interfaces]
CLI[cli]
App[app]
Domain[domain]
Infra[infra]
Interfaces --> App
CLI --> App
App --> Domain
Infra --> Domain
App --> Ports[app/ports]
Infra --> Ports
Ce diagramme illustre uniquement le sens des dépendances entre les couches.
Les responsabilités détaillées de chaque couche sont documentées dans la section Architecture.
Règles importantes
- Un service doit rester propriétaire de son domaine métier.
- La logique métier ne doit pas être dans les resolvers, controllers ou consumers Kafka.
- Les DTO d'interface ne doivent pas être utilisés comme modèles du domaine.
- Les entités ORM ne doivent pas être utilisées comme modèles du domaine.
- Les mappers doivent être explicites entre les couches.
- Les ports doivent être utilisés lorsque la couche applicative dépend d'une implémentation technique.
- Le code partagé entre plusieurs services doit aller dans
libs/feelbat. - Si vous vous demandez pourquoi une convention existe, consultez les pages de la section Architecture.
Pour aller plus loin
Cette page présente uniquement les conventions de structure du backend.
Les concepts d'architecture sont documentés séparément afin de distinguer les règles d'organisation des explications techniques.
À retenir
domaincontient le coeur métier.appcontient les cas d'utilisation et les ports.infracontient les implémentations techniques.interfacesexpose le service vers l'extérieur.cliexpose des commandes internes si nécessaire.sharedcontient uniquement les utilitaires internes au service.- Chaque couche a une responsabilité claire afin de limiter le couplage et faciliter les tests.