Canonical Models are Incompatible with Domain Driven Design

A canonical model is defined as a design pattern used to communicate between different data formats.

Let's think of a tourism company. A canonical model would be, for example, a model of everything that has a meaning for this company. Try to picture it. It would model trips, flights, hotels, payments, invoices, customers, people, product, luggage, holiday packages, etc. Every single concept would have attributes, a customer would have a name, an address, an identifier, etc.

And since canonical models serve a communication purpose, we can think of Json or Xml as its format, for example. So we are talking about a formal representation of the things a business deals with. Every single application would use this canonical model to communicate with other applications within the same enterprise. It does not mean that the applications should use the canonical model for their business logic, but it is expected that they understand it and use it to communicate.

It is something that enterprise architects use and design as their silver bullet to model the whole enterprise world. It's no surprise that often they can take up to several years, depending on complexity, to finalise such an epic task. Sometimes, I have heard, some of them have succeeded (at least at creating it, not sure whether the success covers the understanding and its usage).

Trying to model the world is not an easy and straightforward task and will often result in an over complex model to satisfy all the specific needs.

Domain Driven Design is precisely an approach to software development that tries to tackle complexity by separating concerns, by creating boundaries between different contexts. The famous term ubiquitous language tells us that business or domain experts and developers should be speaking the same language and using the same terms to avoid misconceptions and to remove the need to translate terms and engage all in clear conversations. But this does not mean that a canonical model would be the representation of the ubiquitous language.

Think about it, a customer has not the same meaning for somebody who works in the sales orders department and for somebody who works in the inventory management. A customer within the sales orders context may mean a person who books a holiday package, but a customer within the inventory management may refer to travel agencies that query about availability of certain products.

How could we possibly model something that does not take into consideration the different meaning depending on the context we are in? We simply can't, and that's why a Canonical Model and Domain Driven Design are incompatible.

In fact, a canonical model is generally so polluted with things that don't have a meaning for a particular context or, even worse, with things that have several meanings to satisfy every different context, that the task to decode it and discriminate the important from the irrelevant is tedious. This is ironic because the canonical model's purpose was to make things easier. Easier... for the enterprise architects, of course, often isolated from real business needs and more focused on the infrastructure.

If you are practising Domain Driven Design and you are unlucky enough to having to work with a canonical model.. well.. I am sorry. But try to make the most of it and at least:

  • Do not ever pollute your domain with concepts irrelevant for your domain. If you are working in a bounded context that has to do with bookings, your domain should not know anything about invoices, for example. That's probably someone else's responsibility.
  • Do not ever let the canonical model reach your domain. The previous statement was about not polluting your domain with irrelevant things for your business logic, but actually you cannot use the canonical model as your domain model at all. I am not talking about simply ignoring the irrelevant things, I am talking about having some ACL (Anticorruption Layer) outside your domain to translate the canonical model from the external world into something (event?) that is more meaningful to your domain.
If you are practising Domain Driven Design in a large organization and have the temptation or hear about somebody having the temptation of modelling the whole enterprise (one model to rule them all) with a canonical model, please convince them not to do so. It's an anti-pattern in DDD.