node
backend
nest.js
alpha

Cascade delete of entities

Author: Mateusz Koteja

Problem context

Sometimes executing action on the backend side requires to call services from several domains. That might cause mixing domain contexts and circular dependencies between modules. Events allow you to separate those contexts by executing action in one domain and propagating an event to let other domains know about that.

Example: Deleting some organization might require you to remove all the users in that organization along with their data.

const deleteOrganization = async (organizationId: number, transaction: Transaction) => {
  // That's okay
  await organizationRepository.deleteById(organizationId, transaction);

  // Quite okay, organization might be aware of the users inside.
  await userService.deleteByOrganizationId(organizationId, transaction);

  // Organization domain shouldn't know that. It should be managed by a different domain.
  // Additionally File/Chat domains probably shouldn't know anything about organization domain
  await fileService.deleteUserPhotosByOrganizationId(organizationId, transaction);
  await chartService.deleteUserChatsByOrganizationId(organizationId, transaction);
};

That problem might be solved with emitting an even, but it will not work properly with transactions as events are asynchronous and the transaction will be committed before all the events are handled.

const deleteOrganization = async (organizationId: number, transaction: Transaction) => {
  // That's okay
  await organizationRepository.deleteById(organizationId, transaction);

  // That will not work and the transaction will be commited before all other domains will execute their logic.
  eventBus.publish(new OrganizationDeletedEvent(organizationId, transaction));
};