Aller au contenu

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

  • domain contient le coeur métier.
  • app contient les cas d'utilisation et les ports.
  • infra contient les implémentations techniques.
  • interfaces expose le service vers l'extérieur.
  • cli expose des commandes internes si nécessaire.
  • shared contient uniquement les utilitaires internes au service.
  • Chaque couche a une responsabilité claire afin de limiter le couplage et faciliter les tests.