Skip to content

Instantly share code, notes, and snippets.

@sroccaserra
Last active July 9, 2017 22:30
Show Gist options
  • Save sroccaserra/545ffd2c3f246fdfac35841e60b0624d to your computer and use it in GitHub Desktop.
Save sroccaserra/545ffd2c3f246fdfac35841e60b0624d to your computer and use it in GitHub Desktop.
Notes brutes sur le BBL "Domain Driven Architecture" du 16 déc. 2016, par @lilobase

Domain Driven Architecture

2016-12-16

Mes notes brutes sur le BBL "Domain Driven Architecture" du 16 décembre 2016, par @lilobase chez @novencia.

  • Même language = paramount (le top)

  • Ne jamais contraindre le métier

  • Framework fullstack = poubelle (car le métier se retrouve éparpillé dans des répertoires imposés par le framework et mélangé avec la couche infra et applicative)

  • CRUD = pire saloperie (car on spécifie la persistance plutôt que le métier, et on n'utilise plus les verbes du métier)

  • Archi Dossier <- celle du métier

  • Héritage = uniquement spécialisation d'un type, tout le reste composition ou agrégation.

Agrégats DDD : durée de vie liée, ligne de facture dans facture.

Ex de durée de vie pas liée : client dans facture

Use case qui modifie : command DTO Use case qui ne modifie pas : query DTO

Command bus : lier des commandes à un handler (qui orchestre les transactions métier, transaction script)

Des middlewares dans le bus, comme validation de type, mais jamais validation métier

Toujours parler à la racine d'un agrégat, pas de raccourci.

Contexte A : un Catalogue contient des Produits qui sont des Entités.

Contexte B : Invoice qui contient des InvoiceLine et des Produits. Dans ce contexte, le produit n'est plus une Entité, il devient un ValueObject. Deux concepts différents qui ont le même nom mais pas le même sens en fonction du contexte.

Bounded contexts hermétiques. Sortir les concepts transverses, les mettre dans SharedKernel. Attention, c'est probablement une énorme connerie donc se poser la question plusieurs fois avant de le faire. Jamais les Utilisateurs dans shared. Context Authent & Identité. Pour l'Invoice, des Acheteurs.


EventSourcing très compliqué, éviter.

Un répertoire "model", avec un rep "invoice" (souvent le nom du rep est le nom de l'agrégat)

C'est l'agrégat root qui est responsable de toutes les validations. Une fois instancié, on sait qu'il est valide.

Une interface InvoiceRepository, avec en général trois méthodes : save() (i.e. upsert), exists(), findById(). Note : on est toujours dans la partie Commands. Ne jamais confier l'ID (sa génération) de l'agrégat à la BDD. ID métier (plaque d'immatriculation) ou si possible pouvoir le générer de n'importe-où (hash du contenu).

Une table avec une colonne ID, une colonne contenant l'objet serialisé, et éventuellement quelques colonnes pour les recherches (dates).

Un répertoire "infrastructure", avec un répertoire "invoice", une classe InvoiceSQLRepository chargé de serialiser. Un builder.

Le catalogue expose un service, qui passe une serialisation d'un produit, qui à travers une translation map donne un produit côté invoice.


Queries -> querybus

InvoicesSQLQueries InvoicesReddisQueries

Pas les mêmes datastores que les commandes. Au save de l'agrégat, un événement est propagé pour mettre à jour les projections. Les projections peuvent être reconstruites from scratch.

BDD graph: objets très légers. Juste des id et des relations, les ID pointent sur du reddis qui dépote.

Mongo : bien pour des données arborescentes (pas de relationnel pour ne pas sortir du shard).


Du JSON entre bounded contextes. Ensuite si besoin, HTTP.

Anti corruption layer.

Au dessus du CQRS : un proxy http en js.


Gestion d'erreurs

La commande qui échoue envoie un évent dans le bus de statut.

Note : les différents bus ne sont ni dans le contexte ni dans le proxy.

Un endpoint "xxx/commands" pour les contextes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment