Présentation

RDD est un framework qui vous permet de développer sans effort une API REST qui suit les préceptes architecturaux du DDD.

Mieux, RDD vous permet d’exposer la même API, qu’elle soit appelée de la couche web ou depuis votre code du domaine.

GET /api/users?firstName=like,SO
var usersCollection = container.Resolve<IUsersCollection>();
usersCollection.Get(u => u.FirstName.Contains("SO"));

Il se base sur le principe des Collections, décrit en anglais sous la forme de Repositories ici.

Le DDD met l’accent sur les entités, RDD met l’accent sur les collections d’entités. Ce qui signifie que le client du domaine s’adresse non plus directement aux entités mais aux collections qui représentent ces entités. Chaque collection gère un type d’entité et chaque entité est gérée par une collection.

Néanmoins, il convient de répartir les responsabilités entre la collection et ses entités, afin de ne pas aboutir un domaine anémique. La collection gère tout ce qui concerne une ou plusieurs  entités, l’entité gère ce qui la concerne elle-même directement.

var user = usersCollection.GetById(123);
user.Address = new Address("123 rue de Paris", "Lyon");

RDD expose directement via une API web les collections du domaine. Ce qui signifie qu’il n’existe pas de DTO dans RDD. L’API web respectant les principes REST, elle ne peut accéder aux collections que via les 4 verbes HTTP (GET/Get, PUT/Update, POST/Create, DELETE/Delete).

POST /api/users
{ firstName: "Jean", lastName: "Dupuis", ... }

var user = JsonConvert.Deserialize<User>(data);
usersCollection.Create(user);

Seuls des appels internes au domaine pourront éventuellement faire appel à d’autres méthodes spécifiques des collections.

var user = usersCollection.GetByLogin("jdupuis");

Toutes les ressources exposées par votre API REST doivent avoir un sens métier, puisqu’elles doivent également respecter DDD. Ce qui signifie que vous ne pouvez pas créer une route web adhoc pour un processus particulier. Vous devez exprimer ce processus sous la forme d’une ressource.

POST /api/users/move
{ userId: 123, moveTo: { street: "123 rue de Paris", city: "Lyon" } }

var move = JsonConvert.Deserialize<Move>(data);
usersCollection.CreateMove(123, move);

Ce mécanisme d’expression de processus sous forme de création de ressource rend le système global plus simple et plus monotone. On raisonne toujours sur des ressources, en consultation ou en création/modification/supression, via des collections.

Les collections permettent en outre de gérer nativement les traitements par lot. Les entités ne sont plus isolées les unes des autres, la collection apporte de la cohésion à l’ensemble.

POST /api/departements/usersTransfer
{ fromId: 123, toId: 124 }

var departmentsCollection = container.Resolve<IDepartmentsCollection>();
var userTransfer = JsonConvert.Deserialize<UserTransfer>(data);

departmentsCollection.CreateUserTransfer(userTransfer);

Ce mécanisme permet, en outre, de mieux gérer les logs, puisque la matérialisation via des ressources incite à persister ces ressources, et donc à logguer ces processus.