{"id":13621986,"url":"https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda","last_synced_at":"2025-05-16T00:07:02.673Z","repository":{"id":150906552,"uuid":"623359273","full_name":"bitloops/ddd-hexagonal-cqrs-es-eda","owner":"bitloops","description":"Complete working example of using Domain Driven Design (DDD), Hexagonal Architecture, CQRS, Event Sourcing (ES), Event Driven Architecture (EDA), Behaviour Driven Development (BDD) using TypeScript and NestJS. Like what you see? Don't forget to star! ⭐ ^^^","archived":false,"fork":false,"pushed_at":"2024-06-18T07:07:01.000Z","size":1122,"stargazers_count":1275,"open_issues_count":1,"forks_count":97,"subscribers_count":15,"default_branch":"main","last_synced_at":"2025-04-08T11:09:50.619Z","etag":null,"topics":["bdd","cqrs","ddd","domain-driven-design","event-sourcing","hexagonal-architecture","jaeger","mongodb","nats","nestjs","nodejs","postgres","prometheus","realtime","typescript"],"latest_commit_sha":null,"homepage":"https://bitloops.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitloops.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-04-04T08:04:33.000Z","updated_at":"2025-04-08T08:03:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"486ed617-a6ec-474a-85a6-6076039200d6","html_url":"https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitloops%2Fddd-hexagonal-cqrs-es-eda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitloops%2Fddd-hexagonal-cqrs-es-eda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitloops%2Fddd-hexagonal-cqrs-es-eda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitloops%2Fddd-hexagonal-cqrs-es-eda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitloops","download_url":"https://codeload.github.com/bitloops/ddd-hexagonal-cqrs-es-eda/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254442854,"owners_count":22071878,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","cqrs","ddd","domain-driven-design","event-sourcing","hexagonal-architecture","jaeger","mongodb","nats","nestjs","nodejs","postgres","prometheus","realtime","typescript"],"created_at":"2024-08-01T21:01:12.684Z","updated_at":"2025-05-16T00:06:57.546Z","avatar_url":"https://github.com/bitloops.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","typescript","Sample Projects"],"sub_categories":["JavaScript / TypeScript"],"readme":"# ddd-hexagonal-cqrs-es-eda\n\n[![Node.js CI](https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda/actions/workflows/main.yml) ![GitHub](https://img.shields.io/github/license/bitloops/ddd-hexagonal-cqrs-es-eda) ![GitHub issues](https://img.shields.io/github/issues/bitloops/ddd-hexagonal-cqrs-es-eda) [![Dependabot](https://badgen.net/badge/Dependabot/enabled/green?icon=dependabot)](https://dependabot.com/)\n\nComplete working example of using Domain Driven Design (DDD), Hexagonal Architecture, CQRS, Event Sourcing (ES), Event Driven Architecture (EDA), Behaviour Driven Development (BDD) using TypeScript and NestJS.\n\n\n![ddd-hexagonal-cqrs-es-eda](https://storage.googleapis.com/bitloops-github-assets/ddd-hexagonal-cqrs-es-eda-2.gif)\n\n# Table of Contents\n\n- [I. Introduction](#i-introduction)\n  - [Overview](#overview)\n  - [Todo application business requirements](#todo-application-business-requirements)\n- [II. Technologies and Technical Features](#ii-technologies-and-technical-features)\n  - [Technical Features](#technical-features)\n  - [Technologies Used - Overview](#technologies-used---overview)\n- [III. Quick start - running the ToDo App](#iii-quick-start---running-the-todo-app)\n  - [Prerequisites](#prerequisites)\n  - [Running the app](#running-the-app)\n- [IV. Design Process and Decisions](#iv-design-process-and-decisions)\n  - [Design Process - Event Storming](#design-process---event-storming)\n  - [Design Decisions](#design-decisions)\n- [V. Running in development mode](#v-running-in-development-mode)\n  - [A. Project Setup](#a-project-setup)\n  - [B. Application Validation](#b-application-validation)\n  - [C. Understanding the project structure](#c-understanding-the-project-structure)\n- [VI. Conclusion](#vi-conclusion)\n  - [❓ Questions](#-questions)\n\n# I. Introduction\n\nBuilding complex software is really hard, and we learnt the hard way how important it is to design your software correctly from the beginning! \n\nThere is plenty of information out there on how to build resilient and maintainable software, but the difficulty is actually implementing it. So we went ahead and built a comprehensive example we wish we had when we started learning these concepts and technologies. \n\nOur team has put a lot of effort into creating a clean, and modular code-base that comes as close as possible to production ready code, aiming to provide valuable insights into advanced software architecture concepts. \n \n## Overview\nThe objective of this project is to provide you a reference implementation on how to design and create maintainable and flexible software applications.\n\nThe code is written using Typescript and NodeJS, using the NEST framework, however, the concepts and patterns used are not bound to any specific technologies.\n\nThe project includes an over-engineered ToDo app that includes the patterns and principles that are necessary if you want your code to be easy to change, resilient and easy to maintain. Below we provide detailed instructions on how to run it\n\nIn addition, you will learn a great deal about software design and architecture patterns and principles such as: \n- Hexagonal Architecture (or Ports and adapters)\n- Domain Driven Design (DDD) and its tactical patterns\n- Behaviour Driven Development (BDD)\n- Event Driven Architecture (EDA) \n- Command and Query Responsibility Segregation (CQRS)\n- Eventual consistency\n- Event Storming\n\nThere are many ways to implement these, so we're eager to get your feedback and open to answer any questions you may have. Join our [Discord](https://discord.com/invite/vj8EdZx8gK) channel if you'd like to exchange some ideas on software design \u0026 development or if you have any questions. \n\n## Todo application business requirements\n\nThe todo application, is basically a simple todo application, with some tweaks.\n\nThe users should be able to register to the todo app. After they register, they should be able to login. \nAfter logging in, they should be able to add todos, to complete a todo, to uncomplete a todo (in case they made it complete accidentally), as well as modify the todo title. In the whole process they should be able to view his todos.\n\nWhen a todo is completed, if this is the first completed todo, an email should be sent to the user to congratulate him for completing his first todo. This operation has to do mostly with the needs marketing team.\n\n# II. Technologies and Technical Features \n\n\n## Technical Features \n\n* **Observability**\n* **Realtime client events**\n* **Logging**\n* **Tracing**: Tracks requests that span through multiple modules/microservices\n* **Easy switching between modular monolith and microservices**\n* **Authentication**\n* **Authorization** (Even at the repository level)\n* **Automatic JWT renewal**\n* **gRPC query caching**\n* **Automatic client code generation using gRPC**\n\n## Technologies Used - Overview\nHere are listed some of the specific technologies used for the implementation of the project:\n* **Authentication**: [JSON Web Tokens - JWT](https://jwt.io/)\n* **Databases - Persistence**: [MongoDB](https://www.mongodb.com/), [PostgeSQL](https://www.postgresql.org/)\n* **Testing**: [JEST](https://jestjs.io/)\n* **External Communication Protocols**: [REST](https://en.wikipedia.org/wiki/Representational_state_transfer), [gRPC](https://grpc.io/)\n* **Frameworks**: [ΝestJS](https://nestjs.com/)\n* **PubSub technology**: [NATS](https://nats.io/)\n* **Message Streaming Technology**: [JetStream](https://docs.nats.io/nats-concepts/jetstream) *by NATS*\n* **Container Technology**: [Docker](https://www.docker.com/)\n* **Tracing-Observability**: [Jaeger](https://www.jaegertracing.io/), [Grafana](https://grafana.com/)\n* **Metrics**: [Prometheus](https://prometheus.io/)\n* **API Gateway - Proxy**: [Envoy](https://www.envoyproxy.io/)\n\n\n# III. Quick start - running the ToDo App\n\n## Prerequisites\nIn order to run the application the following should have been installed on your local machine:\n\n* **Docker** should be installed ([link](https://docs.docker.com/engine/install/))\n* **docker-compose** should be installed, if your docker installation does not install it automatically ([link](https://docs.docker.com/compose/install/))\n\n## Running the app\nIn order to run the application you need to follow the steps below:\n* Run: \n```bash\n git clone https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda.git\n```\n* Navigate  to the folder: \n```bash\ncd ddd-hexagonal-cqrs-es-eda\n```\n\n* Run: \n\n```bash\ndocker compose -p bitloops-todo-app up -d\n``` \nfrom the terminal inside the project **in order to download and run the necessary containers**.\n\nThen the ReactJS front-end application will be visible at: `http://localhost:3000`.\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"400\" alt=\"image\" src=\"https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda/assets/1571105/4570473b-4e67-4050-9935-967acfe0b7c6\" alt=\"Frontend application\" align=\"center\"\u003e  \n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nFrontend React JS application (new version using MVVM!)\n\u003c/p\u003e\n\n# IV. Design Process and Decisions \n\n## Design Process - Event Storming\n\nWe have chosen the [Event storming](https://www.eventstorming.com/) technique to document the functionality and business logic of the todo application.\n\nIn general, [Event storming](https://www.eventstorming.com/) is a **collaborating modelling technique** used to model complex domains, in order to align the software produced with the actual business logic. It matches perfectly with [Domain Driven Design (DDD)](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design) as well as [Event Driven Architecture (EDA)](https://bitloops.com/docs/bitloops-language/learning/software-architecture/event-driven-architecture). \n\nIf you want to know more for this technique, you can check the **Theoretical Review** at the end.\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"900\" src=\"https://storage.googleapis.com/bitloops-github-assets/Todo%20event%20stroming%20new.png\" alt=\"Todo Event Storming\" align=\"center\"\u003e\n\u003c/p\u003e\n\nAs you can see after the collaborative discovery, we have identified the following **bounded contexts**:\n\n* **IAM**: Has todo with the user registration and log in.\n*  **Todo**: This is the **core subdomain** of our application (see [DDD](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design))\n*  **Marketing**: This is a **supporting subdomain** (see [DDD](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design)) of our Todo application. \n\nIn the process we have further split some bounded contexts (linguistic boundary), to more fine grained modules.\n\nThe processes of the system as were discovered are the following:\n\n* **User Log In process** (IAM Bounded Context)\n* **User registration process** (IAM Bounded Context)\n* **Todo process** (Todo Bounded Context)\n* **Onboarding process** (Marketing Bounded Context)\n\n## Design Decisions\n\nSome parts of the system need to have information which is located in other parts of the system. \n\nMore specifically, the Marketing bounded context, **needs to know when a todo is completed** and run its business logic to send an email when the first todo is completed.\n\nMoreover the Marketing Bounded contexts **needs to have information concerning the email** of each specific user, in order to be able to send an email.\n\nThe problem in this case is that the email information belongs to the IAM bounded context. So in order for the marketing bounded context to have the knowledge of the specific users's email, either it can make a sync request to the IAM bounded context, or it can listen to integration events from the IAM bounded context, in order to hold a local email information (via [eventual consistency](https://en.wikipedia.org/wiki/Eventual_consistency)).\n\nIn this project the decision was to keep a local repository in the Marketing bounded context, of the users and their emails, updated by listening to integration events from the IAM bounded contexts (**user registered** and **user email changed**). \n\n# V. Running in development mode\n\n## A. Project Setup\n\n### Prerequisites\nIn order to run the application the following should have been installed on your local machine:\n\n* **NodeJS** should be installed ([link](https://nodejs.dev/en/learn/how-to-install-nodejs/))\n* **Docker** should be installed ([link](https://docs.docker.com/engine/install/))\n* **docker-compose** should be installed, if your docker installation does not install it automatically ([link](https://docs.docker.com/compose/install/))\n* **npm** and or **yarn** should be installed ([npm link](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm), [yarn link](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable))\n\n### Running the app\n\nAfter all the necessary have been installed on your local machine, you should follow the **steps** mentioned below to run the application:\n\n* Run: \n```bash\n git clone https://github.com/bitloops/ddd-hexagonal-cqrs-es-eda.git\n```\n* Navigate  to the folder: \n```bash\ncd ddd-hexagonal-cqrs-es-eda/backend\n```\n* Run: \n    ```bash\n    yarn install\n    ``` \n    if you are using **yarn**  \n    or: \n    ```bash\n    npm install\n    ```\n    if you are using **npm**, from the terminal inside the project **to install the necessary packages**.\n\n* **Start docker on your machine**.\n* Run \n  ```bash\n  docker compose -p bitloops-todo-app up -d\n  ``` \n  from the terminal inside the project **in order to download and run the necessary containers**.\n* Create a `.development.env` file inside the root project and copy and paste the contents of the `.template-env`, which is located in the root of the project inside it.\n* Run: \n    ```bash\n    yarn start:dev\n    ``` \n    or \n    ```bash\n    npm start:dev\n    ``` \n    to start the server.\n\n## B. Application Validation\n\n### Test the application is running\n\nIn order to test the application is running we could use a client  \nThe application is using **REST** for the authentication part and **gRPC** for the Todo part.\n\nThose tools could be helpful in the development process as well.\n\n#### Postman\n\nSo we recommend to test the application with a client tool that supports both. Such tool could be [Postman](https://www.postman.com/product/what-is-postman/).\n\nYou may find tutorials on how to use **Postman** for REST and gRPC requests below:\n\n* REST ([link](https://hevodata.com/learn/postman-rest-client/))\n* gRPC ([link](https://learning.postman.com/docs/sending-requests/grpc/first-grpc-request/))\n\nTo just test the app is app and running you can just invoke `http://localhost:8082` URI with Post request as shown in the picture below:\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"900\" src=\"https://storage.googleapis.com/bitloops-github-assets/app-testing-confirmation.png\" alt=\"App Running Confirmation\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nThe server should respond with the message shown in the picture\n\u003c/p\u003e\n\n\n#### cURL (only for initial testing) \n\nA faster way to test the app works is to use **[cURL](https://curl.se/)**. In most cases cURL is already installed in your operating system. If not you can download **cURL** [here](https://curl.se/download.html).\n\nTo just test the app is app and running you can just run the following command on terminal:\n\n```curl http://localhost:8082/```\n\nThe server should respond (in the terminal) with: \n```{\"statusCode\":404,\"message\":\"Cannot GET /auth/register\",\"error\":\"Not Found\"}```\n\n\n### Running the application tests\n\nIn order to run the tests of the application run the following on the terminal:\n\n`yarn test` or `npm test`.\n\n## C. Understanding the project structure\n\nThe main project structure is located at the `/src` folder. \nThe starting point for the whole application is the `src/main.ts` file.\n\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"500\" src=\"https://storage.googleapis.com/bitloops-github-assets/project-structure.png\" alt=\"Project Structure\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nProject Structure Overview\n\u003c/p\u003e\n\nThe main folders are the following:\n\n* api\n* bounded-contexts\n* config\n* lib\n* proto\n\n### API Folder\n\nThe api folder contains the **presentation layer** of the application (driving adapters of the infrastructure layer of the [Hexagonal Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/hexagonal-architecture)), containing the **authentication controllers** (REST) as well as the **todo controllers** (gRPC).\n\nIt also contains the [Data Transfer Objects (DTOs)](https://en.wikipedia.org/wiki/Data_transfer_object) for those controllers.\n\nThe main operation of the **presentation layer (controllers)** is to send **commands** and **queries** via the [PubSub](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) system ([NATS](https://nats.io/) in this case), which will asynchronously invoke the application layer via the **command and the query handlers**- (more information concerning the application layer could be found below).\n\nThe application layer (command and query handlers) after executing, they respond to the presentation layer (controllers) via the [Request-Reply pattern](https://natsbyexample.com/examples/messaging/request-reply/go/). \n\n### Bounded-Contexts Folder\n\nThe bounded-contexts folder contains the **data access layer** (driven adapters of the infrastructure layer) - concrete implementations of the ports ([Hexagonal Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/hexagonal-architecture)) of the application, organised by the specific **bounded contexts** ([DDD](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design)) of the application. These concrete implementations are specific **repository implementations** as well as specific **external service implementations**. \n\n\n### Config Folder\nContains the configuration files for the application.\n\n### Lib Folder\nContains the core of the application (inside the `bounded-contexts` sub-folder), containing the **application layer** and the **domain layer** of the application.\n\nThe sub-folders (e.g. `bounded-contexts/lib/todo`) represent the exact bounded contexts ([DDD](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design)) of the application. In our case these bounded contexts represent a conceptual linguistic boundary. \n\nInside each subfolder of each bounded context there is another folder which represent the specific module (e.g. `bounded-contexts/lib/todo/todo`). \n\nIn our case each module represents a logical boundary inside the linguistic boundary of the bounded context. This means that one bounded context (linguistic boundary), could have more than one module (logical boundary) inside (see  [DDD](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design)).\n\n### Module Structure\nEach module structure contains the following folders:\n* application\n* commands\n* queries\n* domain\n* contracts\n* ports\n* tests\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"400\" src=\"https://storage.googleapis.com/bitloops-github-assets/module-structure.png\" alt=\"Project Structure\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nModule Structure Example\n\u003c/p\u003e\n\n#### Application Folder\nRepresents the **application layer** use cases of the specific module.\nIn this project we have implemented a flavour of the [CQRS pattern](https://martinfowler.com/bliki/CQRS.html). \nSo in general inside this folder reside:\n* Command Handlers\n* Query Handlers\n* Event Handlers (see [Event Driven Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/event-driven-architecture))\n* Application Layer Errors\n\n**Event handlers** also belong to the application layer. In general there are two types of event handlers:\n* **Input Event Handlers**: They listen to events (domain or integration events) and transform them to commands.\n* **Output Event Handlers** : They listen to domain events and transform them to **integration events**. (More on integration events later)\n\nThe event handlers are really important, since they help in building loosly coupled systems ([Event Driven Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/event-driven-architecture)).\n\n#### Commands folder\nCommands also belong to the **application layer** of the specific module. Commands (see [CQRS pattern](https://martinfowler.com/bliki/CQRS.html))  represent the data structure which triggers the command handlers.\n\n#### Queries folder\nQueries also belong to the **application layer** of the specific module. Commands (see [CQRS pattern](https://martinfowler.com/bliki/CQRS.html))  represent the data structure which triggers the query handlers.\n\n#### Domain folder\nThe Domain folder represents the **domain layer** of the module, containing all the elements of the tactical patterns from [Domain Driven Design (DDD)](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design). Like: **Value Objects**, **Entities**, **Root Entities (Aggregates)**, **Domain Events**, **Domain Errors** etc. \nThis folder also contains **Read Models** (see CQRS) as well as **Rules** which represent a way to express the rules inside the domain elements (Value Objects \u0026 Entities). \n\n#### Contracts folder\nRepresent the way a specific module communicates with the other modules, in **loosly coupled** way ([Event Driven Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/event-driven-architecture)).\n\nThis is being achieved via **integration events** ([link](https://codeopinion.com/should-you-publish-domain-events-or-integration-events/)).\n\nUtilising integration events is the way for a module to communicate to other parts of the system (modules) that something has happened.\n\nSince those integration events could break the operation of some other modules if their contract change (the data inside the integration event), it is **necessary to also include a version**. Each time a change is made to an integration event, a new version is triggered without breaking parts (mostly modules) of the system which listens to the old contracts.\n\nA common way to emit integration events is via **transforming the domain events of the domain layer into integration events**, via event handlers.\n\n#### Ports folder\nThis folder contains the **interface (see [Hexagonal Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/hexagonal-architecture)) between the application layer and the infrastructure layer** of the application, and more specifically the **data access layer** (adapters for the specific repository concretions as well as external services concretions). \n\nThose ports are being used as dependencies inside the **application layer** (Command Handlers, Query Handlers and Event Handlers), to achieve the [Dependency inversion principle](https://en.wikipedia.org/wiki/Dependency_inversion_principle) - **D** from [SOLID](https://en.wikipedia.org/wiki/SOLID). Which is the principle which [Hexagonal Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/hexagonal-architecture) uses to achieve plugging different adapters to the same port.\n\n\n#### Tests folder\nThis folder contains the use case tests/ or **behaviour driven tests** (from [BDD](https://bitloops.com/docs/bitloops-language/learning/behavior-driven-development)).\n\nThese tests are testing the behaviour of the system, which means they **test the business logic** by testing the **application layer** (Command Handlers, Query Handlers).\nTesting the business logic via the **application layer**, and not from the **domain layer** (via **unit tests**) helps changing the domain layer frequently **without having to change all the unit tests each time**.\n\nThe tests use **mock repositories** and **mock services** as adapters (concretions) of the ports to **emulate actual repositories and services**. This helps to **test the business logic fast**, **without using actual databases and external services** to test the business logic.\n\n\n### proto folder\nThis folder contains the proto ([protobuf](https://protobuf.dev/) - protocol buffers) files which are mandatory for defining the [gRPC](https://grpc.io/) interface necessary to setup the **todo** api controllers located at the `src/api` folder. \n\nCommunication via **Protocol Buffers** have many advantages than communicating via JSON since the message sent via the wire is in binary form thus slimmer and they also communicate the data type in a **programming language agnostic way**. To read more  You can read more about them [here](https://en.wikipedia.org/wiki/Protocol_Buffers). \n\n# VI. Conclusion\n\nOur team is privileged to have had the opportunity to work with such powerful software design patterns and cutting-edge technologies. We've learned a lot over the past few months, and we're excited to share our knowledge with other developers who are passionate about building great software. \n\nWe would love to keep in touch with people that are interested in this subject and have some ideas to share. Catch us on [Discord](https://discord.com/invite/vj8EdZx8gK) if you have any questions or suggestions. \n\nWe would also love to see some contributions!\n\n## ❓ Questions\n\nIf you have any questions, clarifications or would like some help on your own project, join our [Discord channel](https://discord.gg/vj8EdZx8gK). We already have a few community members learning and sharing knowledge about software development design patterns.\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/star-us.gif\"\n\u003c/p\u003e\n\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n# 📚 Theoretical Review\n\nBelow is a summary of all the software architecture and design patterns used in the example above from a theoretical perspective. These are all based on available resources, and many references are provided for deeper research. \n\n## Table of Contents\n\n- [Software Architecture](#software-architecture)\n  - [Layered Architecture](#layered-architecture)\n    - [Separation of concerns benefits example](#separation-of-concerns-benefits-example)\n    - [Limitations of the classical layered architecture](#limitations-of-the-classical-layered-architecture)\n    - [Modern Layered Architectures](#modern-layered-architectures)\n    - [The Anti-pattern (beware)](#the-anti-pattern-beware)\n  - [Hexagonal Architecture (or Clean / Onion Architecture)](#hexagonal-architecture-or-clean--onion-architecture)\n  - [Ports And Adapters](#ports-and-adapters)\n  - [Driven Adapters vs Driving Adapters](#driven-adapters-vs-driving-adapters)\n  - [Inversion of Control](#inversion-of-control)\n- [Domain Driven Design (DDD)](#domain-driven-design-ddd)\n  - [Key advantages of using DDD](#key-advantages-of-using-ddd)\n  - [Strategic and Tactical DDD](#strategic-and-tactical-ddd)\n    - [DDD \\\u0026 Hexagonal Architecture are Complementary](#ddd--hexagonal-architecture-are-complementary)\n- [Behavior Driven Development (BDD)](#behavior-driven-development-bdd)\n- [Event-Driven Architecture](#event-driven-architecture)\n- [Command and Query Responsibility Segregation (CQRS)](#command-and-query-responsibility-segregation-cqrs)\n- [Event Sourcing (ES)](#event-sourcing-es)\n- [Eventual Consistency](#eventual-consistency)\n- [Event Storming](#event-storming)\n- [🚀 Bringing this all together!](#-bringing-this-all-together)\n- [🙌 Contributing](#-contributing)\n- [👨‍💻 Additional learning resources](#-additional-learning-resources)\n  - [Articles](#articles)\n  - [Blogs](#blogs)\n  - [Videos](#videos)\n  - [Books](#books)\n\n\n\n## Software Architecture\nThe project is designed with a [layered architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/layered-architecture) approach, and more specifically: [Hexagonal Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/hexagonal-architecture) (Ports and Adapters architecture). \n\n\nLayered Architecture is a software architecture that is widely used in modern software development. It is a logical and structured approach to designing software that separates different functional modules of an application into four separate horizontal layers, each with a specific set of responsibilities. This separation of concerns makes the code more modular, maintainable, and scalable, and enables easier testing and debugging.\n\nThis particular architectural pattern has influenced the development of various other architectural patterns, including:\n- [Hexagonal Architecture (also known as Ports and Adapters)](https://bitloops.com/docs/bitloops-language/learning/software-architecture/hexagonal-architecture)\n- [Onion Architecture](https://bitloops.com/docs/bitloops-language/learning/software-architecture/onion-architecture) \n- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)\n\n\nThese patterns have emerged in response to the need to clarify further the concept of layered architecture, and they have each added their own unique features and benefits. However, all these patterns have in common the goal to provide a more modular, flexible, and maintainable approach to building software systems. \n\nTherefore, we strongly recommend understanding the core principles of layered architecture and its relationship to these other patterns, as it will help you better understand these other software architecture patterns, and help you make informed decisions about which approach is best suited to your specific needs and requirements.\n\n### Layered Architecture\nThe use of layers in software is fundamental to obtain what is commonly referred to as [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns). This concept is extremely important if we want the confidence to change some elements of a software system without affecting the other components. This separation makes it very easy to understand how a software system works, and how to manage it. \n\nThe layers communicate with each other via abstractions (or contracts). Those contracts in their simple form could be interfaces (in OOP languages).  \n\nThe standard layers of a classical layered architecture are:\n- **Presentation layer** (also known as UI layer, view layer) -  This layer is responsible for the user interaction with the system. It is responsible for the presentation of the data (e.g. JSON, HTML) and the way of communication with the external world (e.g. REST or gRPC or GraphQL).\n- **Application layer** (also known as service layer, use case layer) - Exposes the business functionality to the upper layer. \n- **Business Layer** (also known as business logic layer (BLL), domain logic layer) - implements the core functionality of the system, containing the business logic.\n- **Data access layer** (also known as persistence layer) - This layer contains the implementation for the communication between the application and the database. Moreover it can implement the communication between the application and some external service.\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"500\" src=\"https://storage.googleapis.com/bitloops-github-assets/Eric%20Evans%20DDD%20Layers.webp\" alt=\"Eric Evans DDD Layers\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nEric Evans Layered Architecture - 2003\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\nIn practice, when utilizing layered architecture and a request comes in, it passes through all layers **Presentation -\u003e Application -\u003e Business -\u003e Data access** and then back to the presentation layer. \n\nThese layers are arranged in a hierarchical order, and each layer provides services to the layer above it and depends on the layer below. The separation of concerns arises as each layer is responsible for handling specific tasks and has limited communication with the other layers. \n\n#### Separation of concerns benefits example\nReturning back to why to use layered architecture, a simple example could be that if we want to add a gRPC endpoint to the presentation layer invoking the same functionality (service or use case) utilised already by a REST endpoint, we can just create a gRPC endpoint in the presentation layers and make it invoke the same service (or use case) from the application layer.\n\nThe key things to consider regarding layered architecture:\n\n- **The dependencies flow downwards.** (e.g. the Presentation layer depends on the Application layer, never the other way around)\n- **At the heart of the classical layered architecture lies the Data access layer.** Ultimately, everything depends on the Data Access layer.\n\n#### Limitations of the classical layered architecture\nThe main limitation of the classical layered architecture is that all layers are dependent on the Data access Layer. Which means that even though it is relatively easy to change the application interface with the outside world (via adding/changing the controller in the Presentation Layer - as mentioned in the example above), it is really hard to change a \n\n#### Modern Layered Architectures\nGiven the growth in complexity of applications, interfaces (mobile devices, tablets, IoTs, etc.) as well as the general shift to cloud, the layered architecture has evolved. Whilst it still maintains the core layers, it is now more commonly known as the n-tier and offers a scalable solution. \n\n\u003c/br\u003e\n\u003c/br\u003e\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"700\" src=\"https://storage.googleapis.com/bitloops-github-assets/2010s-layered-architecture-herbertograca.png\" alt=\"Layered Architecture\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nExample of a Layered Architecture. Source: \u003ca href=\"https://herbertograca.com/2017/08/03/layered-architecture/\"\u003e humbertograça.com\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n#### The Anti-pattern (beware)\nThe Layered Architecture is very intuitive, but beware of creating too many layers and over-complicating the project. It is important to organize a software system by its sub-domains or modules (something we'll see below with DDD), and not solely focused on the layers. \n\n\n\n### Hexagonal Architecture (or Clean / Onion Architecture)\nIn Hexagonal Architecture (as well as in Clean and Onion), the concept of layers is mostly the same, however, the business (or domain) layer is given a higher priority and placed at the heart of the architecture design. This results in the **Data Access Layer (persistence),** now being placed on the outer \"Infrastructure\" Layer. \n\n\u003c/br\u003e\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/hexagonal-architecture-bitloops.svg\"\n\" alt=\"Hexagonal Architecture\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nDetailed Hexagonal Architecture. Source: Bitloops\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\nAs you can see in the image above, the Hexagonal Architecture has same 4 layers, which are sometimes grouped into 3 layers, however, the Domain Layer is at the centre, followed by the Application Layer around it, and the final layer being the Infrastructure Layer around it.\n\nSo once again, you have the same layers as the Layered Architecture:\n- **Infrastructure layer**\n   - Presentation Layer\n   - Data Access Layer\n- **Application Layer**\n- **Domain Layer**\n\nMoreover, the flow of dependencies is actually very similar, but this time it goes from the outside to the inside, more specifically from the Infrastructure Layer (which includes Database, User Interfaces, etc.), to the Application layer and then from the Application Layer to the Domain layer. \n\nEssentially, this means that the Domain Layer does not have any dependency on any of the other layers, allowing it to be simplified and defined exactly as needed.\n\nThe combination of the **Application and Domain Layers** is commonly referred to as the **Application Core Layer (or Core Layer)** in relevant bibliography. Below is a brief explanation to each of the main components of the Hexagonal Architecture, but do refer to this [link](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design) if you want a detailed overview.\n\n### Ports And Adapters\nThe application core (Domain and Application Layer) which is at the center of the application, needs to be connected to specific concrete technologies of the infrastructure layer (Presentation and Data Access layer).\n\nIn order to achieve this whilst maintaining the essence of separation of concerns, two concepts are required: \n\n- **Ports:** Contracts (Interfaces) to plug in specific concrete implementations. They are essentially a specification of how to use the application core. Ports reside inside the Application Core and is composed of one or more interfaces and data transfer objects (DTOs)\n- **Adapters:** Actual implementations of the ports contracts. They are essentially responsible for implementing the code that will allow the Application Core to communicate with the external world.\n\n💡 There could be many adapters for a specific port, which is the reason why you're able to switch or add infrastructure very quickly if your code is setup this way. \n\n\u003e **Example:** if we have a port for an email service (Data Access layer), and we have already implemented an adapter utilising a specific mail server at the moment (e.g. SendGrid adapter) we could easily create another adapter (e.g. Twilio adapter) which implements the same port utilising a totally different service provider. This requires ZERO changes to the Domain or Application Layer.\n\nWith this concept, it is easy to see how we can change database technologies, via creating different adapters for the same database port, or any other external system for that matter. \n\n### Driven Adapters vs Driving Adapters\nAdapters can either be **Driving** or **Driven**. The difference is simply whether the adapters belong to the Presentation (User Interface) or the Data Access layer of the Infrastructure Layer.\n\n- **Driven Adapters:** Belong to the Data Access part of the infrastructure layer\n- **Driving Adapters:**  Belong to the Presentation part of the infrastructure layer\n\n\n\n### Inversion of Control\nThe **key difference** between a classical layered architecture and Hexagonal/Clean/Onion architectures, is the **flow of dependencies.** In the Hexagonal Architecture the Adapters depend on a specific tool and a specific port (through an interface), however, the business logic only depends on the port and doesn't depend on any adapter or external tool. So the direction of dependencies is always pointing towards the centre (the Domain Layer)\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n## Domain Driven Design (DDD)\nDDD is a software development approach or methodology that really focuses on building a deep understanding of a business domain, creating a map or model of the processes and rules of that particular business.\n\nIn fact, DDD is not about coding, but its more a philosophy about how to build software for complex domains, and simplifying the the development of systems that solve that domain's problems. \n\n**In essence, DDD has three core principles:**\n- Focus on the core domain and logic to build domain models\n- Use the domain model as a base for all software designs\n- Collaborate with domain experts to improve the domain model and resolve any emerging domain-related issues\n\n### Key advantages of using DDD\n- **Common Language** – DDD promotes the creation of terminology and definitions that everyone understands and uses, and are specific to a project - this is commonly referred to as the **ubiquitous Language**. This may seem trivial, but the improvement in communication between developers and domain experts, as well as between developers themselves, has a huge productivity boost\n- **Reliable code** - Applying the DDD concepts leads to cleaner, more reliable code that is easy to test\n- **Maintainable code** - Software built with a DDD mindset is easier to understand and change since the code and the business processes are aligned\n- **Faster development** - Well structured and organized code allows developers to develop new features, extensions and improvements / iterations much faster\n\n\n### Strategic and Tactical DDD\nUltimately, DDD helps model software that domain experts understand and agree with, and developers can manage more effectively. It basically provides the bridge between between domain experts (business specialists) and software engineers (Product \u0026 Tech).\n\nIn order to achieve this, DDD is generally thought of from 2 perspectives:\n\n1. **Strategic: this refers to a higher level modeling of the domain by using a ubiquitous language, breaking up a system into bounded contexts and clearly defining the context maps, ensuring the entire team/organization is aligned.**\n\n2. **Tactical: this is commonly referred to as the building blocks of DDD as it is a bit more spec- ific in nature and helps engineers more clearly define these rules and processes. This includes entities, Value Objects, Services, Repositories, etc. which we explain further below.**\n\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/domain_driven_design_tactical_strategic_patterns.png\"\n\" alt=\"Strategic and Tactical DDD Patterns\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nStrategic and Tactical DDD Patterns. Source: \u003ca href=\"https://www.thoughtworks.com/en-us/insights/blog/architecture/domain-driven-design-in-functional-programming\"\u003e thoughtworks\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n#### Strategic: Building a Domain Model\nFrom a strategic perspective, DDD focuses on understanding the domain and building an accurate model. To achieve this, 4 key concepts need to be understood: \n\nExplaining 4 key components of DDD is necessary:\n\n- **Domain / Subdomains:** A domain is the heart of any organization, and is a set of rules, requirements, processes and guidelines that define how an organization interacts with its customers, partners, suppliers and any other relevant stakeholders. There are 3 types of subdomains, and each has a different priority level:\n-- **Core Domain:** This is the domain that makes this product unique and adds the most value to its users. It has the highest priority and focuses and on what the organization really needs to excel at. \n-- **Supporting Domain:** This domain supports the overall project, but is not critical. There may be some customization, but its not something unique to the project\n-- **Generic Domain:** These domains can easily be outsourced or provided by a standard market solution. There is no special feature or uniqueness\n\n- **Ubiquitous Language:** This encompasses all the terms and words used to define the domain model, and is generally created through collaboration with domain experts. This language is then used by all team members when discussing activities related to the team’s application.\n- **Bounded Contexts:** This is a conceptual boundary that contains parts of an application that fit into a specific model. Its typically a subsystem or the work of a specific team and revolves around a specific business domain.\n- **Context Mapping:** This basically defines how bounded contexts interact and communicate with each other. Having clarity on the boundaries as well as the collaboration expectations will improve greatly the quality and speed of product development.\n\n\u0026nbsp;\n\n#### Tactically: Implementing DDD\nThe tactical patterns deal with the actual implementation once a domain model has been defined. One of the first principles is the use of a Layered Architecture (in this case a Hexagonal Architecture) to ensure the code not be intertwined with different functionalities. Separating the domain logic from all other functionality reduces confusion in large and complex systems.\n\n- **Events:** Events allow systems to be designed with reduced coupling between components. Generally, events represent an important business event in the domain and are represented with specific ubiquitous language. They are used in a publish-subscribe manner to trigger other commands or services and can be considered:\n    - **Domain events:** used within a specific bounded context and can reference domain objects, and are commonly used to synchronize state of different aggregates or subscribe to events in the application services and perform infrastructure related tasks.\n    - **Integration events:** are events used to synchronize between bounded contexts, particularly useful when building microservices. These events cannot reference domain objects, usually contain only identifiers of all aggregates which changed state and should use simple types so other systems are able to interpret them. These events are part of the published (not ubiquitous language), meaning changes could impact external systems.\n- **Entities:** These represent concepts in the domain problem that have a unique identity (which does not change over time) and have a life cycle. Entities are composed of value objects and relation to other entities. \n- **Value objects:** These objects are the basic building blocks of any domain model and define important concepts. THey are immutable and replaceable, and unlike entities, have no lifecycle. The lack of value objects may indicate that the entities are overloaded with responsibilities.\n- **Aggregates:** This is probably the most powerful tactical pattern as Aggregates divide bounded contexts into smaller groups of classes, where each group represents concepts closely related to each other that work together. This ensures high-cohesion of a software system. \n- **Factories:** In order to create a new object, Factories are built with a single responsibility: create other objects. The reason Factories are used is that it provides encapsulation given an interface is created to simplify the object creation process, and makes it also easier to change in the future. \n- **Domain Invariant:** The policies and conditions that must always be met in a specific context, as well as what is possible and what is prohibited in the context is defined by Domain Invariants.\n- **Domain Error:** Errors will occur and a well-defined domain layer makes it much easier to detect errors and return an explicit error types, rather than throwing the session and not returning an error.\n- **Domain Service:** A Domain Service is used to encapsulate domain logic and represent business concepts when multiple entities or value objects have a shared responsibility. THey basically orchestrate entities and value objects.\n- **Data Transfer Object (DTO):** A DTO is a special type of class that represents data that comes from external applications, carries data between processes \u0026 defines contracts between them. \n- **Application Service:** In order to orchestrate the necessary steps to complete an operation by a user, Application Services (also known as workflow services, use cases or interactors) as used to manage the communication across the entire application. \n- **Command:** A Command will change data within a system and indicates an intention by a user. \n- **Queries:** A Query only retrieves data from a system without making any changes. Understanding these two concepts is important to understand CQRS explained further below. \n- **Repository:** All the code that handles operations over aggregates (entities and value objects) is placed in a repository. It provides an intermediary between the domain model and the data mapping. \n\nThe above is a summary of DDD and its benefits, however, there are many detailed posts, articles and videos about Domain Driven Design. This [reference document](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design) has a comprehensive overview.\n\n\n### DDD \u0026 Hexagonal Architecture are Complementary\nDomain-driven design and hexagonal architecture go hand in hand given that DDD tactical patterns can be implemented inside the Domain Layer of Hexagonal Architecture. \n\nThe goal of DDD is to build software systems that are closely aligned with the business needs and focus on modularity (separation of concerns), a common language and the creation of a domain model that is easy to understand, maintain, and modify over time. It really focuses on building a create Application Core (domain and application layers)\n\nThe goal of hexagonal architecture is to ensure the entire application works well and serves its users in the best way possible, using (and changing) technologies when necessary. The focus is on building systems that are modular, testable, and maintainable\n\nCombining DDD and hexagonal architecture is not easy (we believe the above domain framework makes it much easier), and there are many advantages: \n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n## Behavior Driven Development (BDD) \n[BDD](https://bitloops.com/docs/bitloops-language/learning/software-design/behavior-driven-development), also known as Behavioral Testing, is all about connecting the technical teams with the business teams manage, map and test the external behaviour of the system. \n\nThe focus is on the expected behavior of the system, and it helps non-technical team members to get a clear picture of the software development process and describes in-depth the expected outcomes. With this focus, there is a higher chance of delivering value to the business as it allows teams to identify and address issues early in the development process. \n\u003c/br\u003e\n\u003c/br\u003e\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/behavior-driven-development-cycle-what-is-bdd.png\"\n\" alt=\"Behavior Driven Development BDD\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nBehavior Driven Development (BDD). Source: \u003ca href=\"https://brainhub.eu/library/behavior-driven-development\"\u003e BRAINHUB\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n\nLike DDD, BDD emphasizes collaboration between developers and business stakeholders, reducing the risk of errors and issues in production. In fact, BDD and DDD are often combined during development processes to test the behaviour of the application layer (use cases), as well as unit tests that focus on specific domain elements but change a lot faster.\n\nIn addition, BDD is commonly used with [Test-Driven Development (TDD)](https://bitloops.com/docs/bitloops-language/learning/software-design/test-driven-development), which is essentially a software development process, similar to BDD, that encourages developers to build test cases that represent the expected outcomes before the development of the actual code.\n\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/behavior-driven-development-cycle-what-is-.png\"\nIf you're interested in learning more about BDD, you can find a detailed description [here](https://bitloops.com/docs/bitloops-language/learning/software-design/behavior-driven-development).  \n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n## Event-Driven Architecture\nEDA is a messaging-based architecture that enables components in a software system to communicate through events. This ensures adequate decoupling. \n\nIn EDA, event producers generate events and publish them to event channels, which then deliver them to event consumers. An event consumer subscribes to specific channels to receive a notification every time an event is published to that channel.\n\nOverall, EDA is viewed as an effective way to design and build software systems that are flexible, resilient, scalable and efficient:\n- **Scalability:** through decoupling its possible to scale each component independently. Key for distributed systems. \n- **Resilience:** the failure of one component does not impact the entire system. There are always dependencies, but many components can continue running if a single component is unable to process the events it receives.\n- **Flexibility:** given this decoupling, each component can be maintained independently as well, making it easier to replace components as the system evolves. \n- **Efficiency:** event driven systems are normally faster at processing requests as they're less resource-intensive than other forms of communication\n\n\u003c/br\u003e\n\u003c/br\u003e\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/Event-Driven-Architecture-diagram.webp\"\n\" alt=\"Event Driven Architecture EDA\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nEvent-Driven Architecture (EDA). Source: \u003ca href=\"https://www.scylladb.com/glossary/event-driven-architecture/\"\u003e SCYLLADB\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n\nThe core components of Event-driven Architecture (EDA) are:. \n\n- **Events:** notifications that are generated by event producers and consumed by event consumers. They carry information about an action or state change within the system.\n\n- **Event producers:** components that generate events. Could be due to a user interaction, a database updates or a sensor reading in an IoT device. Event producers publish events to event channels for event consumers to receive.\n\n- **Event consumers:** components that receive and consume events. They subscribe to event channels and are notified when events are published to those channels. Event consumers react to events they receive.\n\n- **Event channels:** medium through which events are delivered from event producers to event consumers. These are message queues that store and deliver events and can be pub/sub channels, point-to-point channels, and hybrid channels.\n\nIf you would like to learn more about EDA, we have a more complete overview [here](https://bitloops.com/docs/bitloops-language/learning/software-architecture/event-driven-architecture).\n\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n## Command and Query Responsibility Segregation (CQRS)\nCQRS is a software architecture pattern (note: it is not a software architecture style like Hexagonal Architecture) that separates the command and query responsibilities of an application. This pattern has gained popularity as it improves scalability and performance as it provides a way to handle complex data models by separating read and write operations. \n\n- **Command:** A method that modifies or mutates the state underneath the interface, but does not provide any answer with regards to that state\n- **Query:** A method that answers teh current state beneath the interface but does not modify that state before answering it\n\n\u003c/br\u003e\n\u003c/br\u003e\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/CQRS_Detail.png\"\n\" alt=\"Command-Query Responsibility Segregation (CQRS)\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nCommand-Query Responsibility Segregation (CQRS). Source: \u003ca href=\"https://kalele.io/really-simple-cqrs/\"\u003e KALELE\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\nBy following this pattern, you're able to optimize the processes for data retrieval, as well as the processes for data processing. This enables much easier horizontal scaling, better performance and improved user experience. \n\nMaybe most importantly, CQRS improves data consistency by ensuring that write operations are always handled in a consistent and reliable manner. This can lead to fewer errors and a more reliable application overall.\n\n\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n## Event Sourcing (ES)\nES is nothing more than capturing all the changes to an application as a sequence of events!\n\nThink about that. How cool would it be to be able to regenerate your entire application history? Not only would we be able to understand the state, but also understand how we got there. \n\nEvent Sourcing is basically about capturing every single change to an application's data, and store it as a sequence of events, so we can query these events, use them in an event log to reconstruct past events, and even use them for testing purposes. \n\nOne of the key ES principles is to guarantee that all changes to the domain objects are initiated by  event, given we're storing events (if you make changes to your database without the use of an event, then that change will not be captured by the event log and ES becomes incomplete). \n\nWith this, you're able to do:\n- **Complete rebuilds:** Ultimately, you could rebuild your entire application by re-running the events\n- **Temporal Query:** It is possible to understand the state at any point in time in history by simply running the event log until the point in time we want to analyze \n- **Event Replay:** It's also possible to correct passed events and compute the state after reversing or correcting a particular event. \n- **Testing:** If you're keen on running a comprehensive test on a major product addition or enhancement, its possible to run all of the events and understand the implications to the application state\n\nEvent sourcing most definitely sounds like an interesting pattern to implement, however, there are many aspects to consider. If you're looking for more details, the [Marting Fowler](https://martinfowler.com/eaaDev/EventSourcing.html) has a great essay on the topic. \n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n## Eventual Consistency \nSoftware systems, particularly enterprise applications, are built to have high availability and fault tolerance, as well as great performance and scalability. \n\nAchieving all of this is very difficult, especially if we want to ensure data consistency, whilst operating these distributed systems which are running across multiple servers. There are network delays, message loss or server failures that need to be taken into considering. \n\nAs the term applies, eventual consistency is a design model used in distributed software that allows for updates to be made to different parts of the system independently, without requiring that all nodes have an immediate, consistent view of the data. Instead, the system will eventually reach a consistent state, after some period of time.\n\nIn an eventually consistent system, updates may be applied asynchronously and may propagate to different nodes at different rates. This means that different nodes may have different views of the data at any given point in time. However, over time, as updates propagate to all nodes, the system will converge on a consistent state.\n\nTo achieve eventual consistency, systems may use a variety of techniques, such as:\n- **Conflict resolution:** resolving conflicts when they arise\n- **Versioning:** assigning unique identifies to each update, along the system to track the history of changes\n- **Reconciliation:** periodically comparing different views of the data to detect and correct any inconsistencies. \n\nBy using these techniques, eventually consistent systems are able to provide high availability and scalability while still ensuring data consistency over time.\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n\n## Event Storming\n\n[Event storming](https://www.eventstorming.com/) is a collaborating modelling technique used to model complex domains, aligned perfectly with [Domain Driven Design (DDD)](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design) as well as [Event Driven Architecture (EDA)](https://bitloops.com/docs/bitloops-language/learning/software-architecture/event-driven-architecture). \n\nThe main idea is to gather people from all parts of the business (business - domain experts and engineering) to collaborate in order to be able to align the final software system produced with the actual business processes. This way all stakeholders can communicate effectively utilizing the ubiquitous language, and the software would be a reflection with the actual business processes (see [DDD](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design)). \n\nThe Event Storming Process, in a nutshell is a process which could be separated in 3 parts:\n\n* **Big Picture Event Storming** (BPES)\n* **Process Level Event Storming** (PLES)\n* **Design Level Event Storming** (DLES)\n\n### Big Picture Event Storming\nThis is the first phase of Event Storming for which all the participants are gathered and start to add **orange stickies** initially in a wall (or in a collaborative tool), which **represent the events** that can happen in the system and processes, written in past tense. \n\nThen the events are grouped together and put in chronologically order.\n\nIn this part of the event storming some close related events can be spotted. So basically based on those events we can start modularize the system based on the bounded contexts ([DDD](https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design)) we are discovering in the **BPES**. Moreover via this initial stage we can discover some events which belong to the same process - thus **discovering  the system's processes**. Then the most important parts/processes of the system can be spotted, in order to be prioritized as the most important to be developed.\n\nExcept the domain events (orange stickies), in this part of the process dome more stickies could be introduced like: \n* **Hot spots (purple stickies)**: things to be discussed/clarified later\n* **Actors (yellow stickies)**: people/systems who are responsible for the production of the domain event.\n* **Systems (pink stickies)**: External systems which can create domain events in our system.\n\n### Process Level Event Storming\nIn this second part of the Event Storming process, after the domain events of the system have been grouped, and most important processes have been spotted, a more thorough modelling will take place, introducing some more concepts (and stickies):\n\n* **Commands (blue stickies)**: Represents decisions, actions or intent.\n* **Query Model/Read Model (green stickies)**: The necessary information needed for an actor to make a decision.\n* **Policy (Lilac stickies)**: Reactive Logic (\"whenever X happens, we do Y\" ).\n\nIn this part of the event storming process, the business process being modelled will be really close to the software output.\n\n### Design Level Event Storming\nThis is the final part of the event storming process. \n\nDuring the previous parts, some consistent business **rules/constraints** would have arisen during the discussions. These could usually being represented via another flavour of yellow stickies (distinct from the one used for the actors). \n\nThe **Aggregates** (Aggregate Roots) (see [DDD]((https://bitloops.com/docs/bitloops-language/learning/software-design/domain-driven-design))), would be the sum of all closely related business rules (yellow stickies).\n\nAfter including the constraints(aggregates) the Event Storming Session is finally over, and then the development can start for this specific business process.\n\n### Event Storming Syntax\n\nThe general syntax of event storming is the following:\n\n* A **command** can be issued by an **actor** or a **policy**\n* An **event** can be triggered by an **external system** or an **aggregate**.\n* An **event** can **activate a policy** and/or **update a read model**.\n* A **read model** provides information to an **actor**.\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"900\" src=\"https://storage.googleapis.com/bitloops-github-assets/Event%20Stroming%20Syntax.png\" alt=\"Event storming syntax\" align=\"center\"\u003e\n\u003c/p\u003e\n\n### More on Event Storming\n\nFor more on event storming you could check [this repository](https://github.com/ddd-crew/eventstorming-glossary-cheat-sheet) from DDD crew as well as read the original [book](https://leanpub.com/introducing_eventstorming) from Alberto Brandolini.\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n## 🚀 Bringing this all together!\nTo summarize, we have reviewed the following:\n- Hexagonal architecture is a software architecture the places the Domain Layer at the center with no dependencies on any other layer. The Application Layer around the Domain Layer orchestrates the services, and combined the form the Application Core. On the outer layer we have the Infrastructure Layer that comprises the User Interface, Database, etc. The key consideration is that we must use Ports and Adapters to connect the Application Core with the Infrastructure Layer - this ensures clear separation of concerns, improving the modularity, testability and maintainability of a software system.\n\n- Domain-driven design is a software design pattern that helps you build well-defined, easy to understand domain models, more specifically the Application Core (Domain and Application Layers of the Hexagonal Architecture). By applying these principles, the domain is more representative of the business itself and the business logic is easier to change. Moreover, it works particularly well with Ports and Adaptors to maintain the separation we desire between Application Core and the Infrastructure Layer.\n\n- Behavior-driven development is a software development approach that allows you to better understand the expected behaviors of the application, the expected outcomes, and ultimately generates a common understanding between all stakeholders. [BDD](https://bitloops.com/docs/bitloops-language/learning/software-design/behavior-driven-development) is particularly important to increase cohesion between modules and components.\n\n- Event-driven architecture is all about setting up your different services and modules in such a way that they produce or consume events. This increases the resilience and flexibility as the components are decoupled from one another, improving scalability and performance. \n\n- CQRS is all about separating your methods into commands and queries, and never mixing the two. This ensures separation of concerns from a business logic perspective, keeping the code clean, easy to understand and easy to change.\n\n- Event Sourcing is a software design pattern that ensures all changes to objects (database) happens through an event, and that event is stored sequentially in order to have a complete log of all state changes to the application, and be able to rebuild, test or correct states using that log. \n\nHopefully its clear that implementing these software architecture and design patterns will undoubtedly produce high-quality software, that is flexible, resilient and easy to maintain. It will be very easy to onboard new developers to the project, create a new feature, or change a particular technology or infrastructure. \n\nIt's probably also overwhelming as its not easy to implement all this as it requires experience and quite a bit of additional overhead. However, the domain framework above has been created to provide you will all the necessary boilerplate, scaffolding, pipeline and even infrastructure code necessary to build an application that follows these design principles. \n\nBelow is a great diagram inspired by [Herberto Graça!](https://herbertograca.com/) that combines Hexagonal, Clean, Onion, DDD, CQRS and many more concepts \n\n\u003c/br\u003e\n\u003c/br\u003e\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"800\" src=\"https://storage.googleapis.com/bitloops-github-assets/Domain-driven%20Design%20and%20Hexagonal%20Architecture%20and%20CQRS%20and%20Event%20Sourcing.png\" alt=\"Explicit Architecture\" align=\"center\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\nDDD + Hexagonal Architecture + CQRS + EDA: \u003ca href=\"https://github.com/Sairyss/domain-driven-hexagon/blob/master/README.md#pros\"\u003e GitHub\u003c/a\u003e\n\u003c/p\u003e\n\nThe overarching idea is the following:\n- A User makes a request and a Command/Query is sent to the controller using a DTO\n- The Controller maps this through an Adapter and then a Port to an Application Service\n- The Application Service (within the Application Core) handles the Command/Query\n- The Application Service communicates with the Domain Layer (domain services, aggregate, entities) to execute the required business logic\n- The Application Core communicates through Ports and Adapters to the Infrastructure Layer\n- The Infrastructure Layer maps the relevant data, retrieves/persists data from/to a database\n- Through Inversion Control, it passes the data back to the Application Core\n- Once the Application Core has complete its job, the data/confirmation is returned to the Controllers (again through Ports and Adapters)\n- The Controllers return data back to the User\n\nWith this approach, the domain layer cannot be corrupted with other code, there is clear separation of concerns and each component follows a single-responsibility principle. \n\nThis is a general overview and each project needs to be tailored accordingly, with more or less layers/components. Moreover, it is always possible to refactor and improve on these layers at a later stage if required. What is important is to create the foundation for that future refactoring work. \n\n\n\n## 🙌 Contributing\n\nIf you'd like to get involved feel free to learn more about the [Bitloops Language](https://github.com/bitloops/bitloops-language) and contribute to this Repo or our main project.  \n\nYou can also contribute with a star to spread the word!\n\n\u003cp align=\"center\" style=\"margin-bottom: 0px !important;\"\u003e\n  \u003cimg width=\"600\" src=\"https://storage.googleapis.com/bitloops-github-assets/star-us.gif\"\n\u003c/p\u003e\n\n\u003c/br\u003e\n\u003c/br\u003e\n\n---\n\n# 👨‍💻 Additional learning resources\n\n## Articles\n\n- [The Clean Architecture](http://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html) - Robert C. Martin (Uncle Bog)\n- [Better Software Design with Clean Architecture](https://fullstackmark.com/post/11/better-software-design-with-clean-architecture) - FullStackMark\n- [Clean Domain-Driven Design](https://medium.com/unil-ci-software-engineering/clean-domain-driven-design-2236f5430a05) - George\n- [Bounded Contexts are NOT Microservices](https://vladikk.com/2018/01/21/bounded-contexts-vs-microservices/) - Vladikk\n- [Deep Dive into CQRS — A Great Microservices Pattern](https://levelup.gitconnected.com/what-is-cqrs-8ddd74ca05bb) - LevelUp\n- [Clean Event-Driven Architecture](https://valerii-udodov.com/posts/event-sourcing/clean-event-driven-architecture/) - Val's Tech Blog\n- [Clean Architecture with TypeScript: DDD, ONION](https://bazaglia.com/clean-architecture-with-typescript-ddd-onion/) - bazaglia.com\n- [Comparison of Domain-Driven Design and Clean Architecture Concepts](https://khalilstemmler.com/articles/software-design-architecture/domain-driven-design-vs-clean-architecture/) - Khalilstemmler.com\n- [Anemic Domain Model](https://khalilstemmler.com/wiki/anemic-domain-model/) - Khalilstemmler.com\n- [Events: Fat or Thin](https://codesimple.blog/2019/02/16/events-fat-or-thin/#:~:text=Thin%20Events%20shine%20when%20the,in%2Dtime%20processing%20is%20required) - CODE SIMPLE{}\n- [CQRS Software Architecture Pattern: The Good, the Bad, and the Ugly](https://betterprogramming.pub/cqrs-software-architecture-pattern-the-good-the-bad-and-the-ugly-e9d6e7a34daf) - Jawad Margieh\n- [Domain Driven Design and Development In Practice](https://www.infoq.com/articles/ddd-in-practice/) - InfoQ\n- [Combining Domain Driven Design and Behaviour Driven Development](https://baasie.com/2018/02/14/combining-domain-driven-design-and-behaviour-driven-development/) - baasie.com\n- [CQRS](https://martinfowler.com/bliki/CQRS.html) - Marting Fowler\n- [Domain events: Design and implementation](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/domain-events-design-implementation#singl[%E2%80%A6]egates) - Microsoft\n- [Domain-Driven Design and Domain Specific Languages](https://www.infoq.com/presentations/ddd-dsl-evans/) - InfoQ\n- [Domains, Sub-Domains and Bounded Contexts: Explained with example from industry](https://alok-mishra.com/2020/08/17/ddd-domains-bounded-contexts/) - Alok Mishra\n- [DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together](https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/) - herbertograca.com\n\n\n## Blogs\n\n- [Clean Coder](https://blog.cleancoder.com/) - by Robert C. Martin (Uncle Bob)\n- [martinFowler.com](https://martinfowler.com/) - Martin Fowler\n- [Khalilstemmler.com](https://khalilstemmler.com/) - by Khalil Stemmler\n- [@hgraca](https://herbertograca.com/) - Herberto Graça\n- [Alok Mishra](https://alok-mishra.com/) - Alok Mishra\n- [Mr. Picky](https://mrpicky.dev/) -\n- [Nicolò Pignatelli](https://medium.com/@nicolopigna) - Nicolò Pignatelli\n- [bassie.com](https://baasie.com/blog/) - Kenny Baas-Schwegler\n- [CODE SIMPLE{}](https://codesimple.blog/) - Satjinder Bath\n- [Val's Tech Blog](https://valerii-udodov.com/) - Valerii Udodov\n- [Kevin Vogel](https://medium.com/@hellokevinvogel) - Kevin Vogel\n\n\n## Videos\n- [7 Years of DDD: Tackling Complexity in Large-Scale Marketing Systems](https://www.youtube.com/watch?v=DIu1FLD8CsE) - Vladik Khononov, NDC {Sydney} 2018\n- [A Decade of DDD, CQRS, Event Sourcing](https://www.youtube.com/watch?v=LDW0QWie21s) - Greg Young, DDD Europe 2016\n- [More Testable Code with the Hexagonal Architecture](https://youtu.be/ujb_O6myknY) - Ted Young, Webinar 2019\n- [If (domain logic) then CQRS, or Saga?](https://www.youtube.com/watch?v=fWU8ZK0Dmxs) - Udi Dahan, DDD Europe 2017\n- [Herberto Graca - Making architecture explicit](https://www.youtube.com/watch?v=_yoZN9Sb3PM\u0026feature=youtu.be) - Herberto Graça, PHP Srbija 2019\n- [What is DDD](https://www.youtube.com/watch?v=pMuiVlnGqjk) - Eric Evans, DDD Europe 2019\n\n## Books\n- [Domain-Driven Design: Tackling Complexity in the Heart of Software](https://www.oreilly.com/library/view/domain-driven-design-tackling/0321125215/) – Eric Evans\n- [Implementing Domain-Driven Design](https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577) – Vaughn Vernon\n- [Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions](https://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683) – Gregor Hohpe, Bobby Wolf\n- [Clean Architecture: A Craftsman's Guide to Software Structure and Design](https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164) - Robert C. Martin (Uncle Bob)\n- [A Philosophy of Software Design](https://www.goodreads.com/book/show/39996759-a-philosophy-of-software-design) - John Ousterhout\n- [Clean Code: A Handbook of Agile Software Craftsmanship](https://www.goodreads.com/book/show/3735293-clean-code) – Robert C. Martin (Uncle Bob)\n- [Patterns, Principles, and Practices of Domain-Driven Design](https://www.amazon.com/Patterns-Principles-Practices-Domain-Driven-Design/dp/1118714709) – Scott Millett, Nick Tune\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitloops%2Fddd-hexagonal-cqrs-es-eda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitloops%2Fddd-hexagonal-cqrs-es-eda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitloops%2Fddd-hexagonal-cqrs-es-eda/lists"}