Hydrating TypeScript Domain Entities

In Domain-Driven Design, an entity’s constructor is a sacred thing. It really means a new domain object.

For example:

employee-class

When the Employee class is initialized, it’s tagged as newbie automatically to protect our invariants and avoid invalid state for this domain.

Here, we can be sure that calling the constructor means it is literally creating a new Employee for the domain we are solving.

employee-class

It’s all good until you need the other part of CRUD operations. How can we update an existing employee?

You can’t call new and populate the properties in the constructor since it will be tagged as a newbie.

What’s persisted is not entirely new, in a sense. If you think about it, instantiating a new Employee and updating it doesn’t really convey a logical sense.

You can only update an existing Employee or object.

If you’re using a great ORM framework like TypeORM then it should be easy.

The framework will handle hydrating the objects for you without calling its constructor.

employee-class

The drawback is that the entity becomes impure. In DDD, an entity should be pure and separated from implementation details.

An entity’s concern is handling business logic not how it is persisted. Having code annotations on your entities like above will only tie your codebase to the framework you are using.

Plus, modeling in data-first mindset forces you to make compromises in favor of the underlying database schema used, not the other way around.

If we want our codebase to adhere to Single-Responsibility principle, here’s another way we can hydrate our objects.

employee-class

We used Factory to handle the building and transformation of a domain entity. Don’t concern yourself with immutable if it doesn’t make sense to you. I used the library to make it easy to manipulate data structures.

Anyhow, we dynamically created the object, skipping the constructor call, and hydrate the properties through the property descriptor with their attributes. The writable attribute means we can mutate the property at a later time.

Here’s the content of the properties variable if we do it by hand:

employee-class

In our repository, we can use it as is:

employee-class

And the usage will still be the same. employee-class

Our entity is pure again without the annotations. Although, at the cost of having more code.

In any case, we can create helper methods to remove boilerplates around our codebase when we need to.

As long as we can keep the complexity introduced by DDD manageable, we can keep the flexibility of our code for a very long time.


Join my newsletter and get monthly articles on productivity, habits, and decision making in your inbox.