Skip to main content



UseCases (also known as Application Services) are the main features of the application. They coordinate among Entities, Domain Services, handle database commands/queries and can issue out Integration Events. They perform either a COMMAND(like createTodo) or a QUERY(like getTodoById) against the system.

We should strive to push all business domain logic into the domain model, whether that be in Aggregates, ValueObjects or Domain Services. Keep Application Services thin, using them only to coordinate tasks on the model. vaughnvernon2013


Declaring a UseCase
  UseCase UpdateTodoUseCase (todoRepo: TodoWriteRepoPort) {
execute (requestDTO: UpdateTodoRequestDTO): (OK(void), Errors(ApplicationErrors.ToDoNotFoundError)) {
const requestId = UUIDv4(;
const todoFound = this.todoRepo.getById(requestId);
if(NOT todoFound) {
const requestIdString = requestId.toString();
return ApplicationErrors.ToDoNotFoundError(requestIdString);

const title = TitleVO({ title: requestDTO.title });

const todo = TodoEntity({ title: title, completed: requestDTO.completed, id: requestId });
Using a UseCase

The UseCase is used inside a controller like this:

const result = this.updateTodoUseCase.execute(dto);


Declaring a UseCase
  UseCase <identifier name with a UseCase suffix> (<dependencies of UseCase>) {
execute (<DTO>): (OK(<bitloopsPrimaryType>), Errors(<errorIdentifier '|' errorIdentifier...>)) {
Using a UseCase
  this.<use case identifier name>.execute(<dto identifier name>);

References for the above:

Further reading

  1. Vaughn Vernon, Implementing Domain-Driven Design, 2013