Skip to content

Architecture Documentation

hamed shirbandi edited this page Oct 1, 2023 · 39 revisions

Previously, our application was built using a Monolithic architecture. After reaching a stable state, we made the strategic decision to transition from Monolith to Microservices architecture, following the Strangler Application pattern.

In alignment with Microservices architecture principles, we extracted specific services by applying the concepts of Aggregates and Bounded Contexts from Domain-Driven Design (DDD). These services were then developed independently, adhering to the Clean Architecture.

You can explore the code related to the Monolithic version of TaskoMask by visiting this commit.

Development Architecture

As the initial step in refactoring our architecture from Monolithic to Microservices, we designed the development architecture as depicted in the diagram below. This approach allowed us to view the monolith as a single service, facilitating the gradual extraction of individual services over time.

Development architecture

Deployment Architecture

We opted to segregate each service into Read and Write components, a decision made to enhance clarity, maintainability, and flexibility. This separation also empowers us to make informed scaling decisions in a production environment by considering the loads on both the Read and Write sides of a service.

Deployment architecture

Clean Architecture

As illustrated in the TaskoMask development architecture diagram, each service is built upon the Clean Architecture, as depicted in the following diagram

Clean-Architecture

So, generally we have the following layers in each service:

  • Domain
  • Infrastructure
  • Application
  • API
  • Tests

Domain

This layer contains the domain model for the services, we use Rich domain model following DDD concepts for the Write side and Anemic domain model to be used in the Read side.

Infrastructure

Here we config all infrastructure stuff like Database and other cross-cutting concerns like object mapper, mediator, etc. Also, general configuration come from building blocks like message bus, logging, etc.

Application

In this layer we mainly implement use cases. We use the benefits of Use Case Driven Development approach and vertical slice architecture. If you are not familiar with these approaches, we recommend you to have a look on following posts:

API

This is the Presentation part of the services and contains a web API project. These API services are not accessible directly from the outside world and just can be used through API Gateways.

Tests

It contains all Unit & Integration for the service.