{"id":15002597,"url":"https://github.com/fals/cqrs-clean-eventual-consistency","last_synced_at":"2025-04-05T05:08:05.128Z","repository":{"id":62908200,"uuid":"140330846","full_name":"fals/cqrs-clean-eventual-consistency","owner":"fals","description":"CQRS, using Clean Architecture, multiple databases and Eventual Consistency","archived":false,"fork":false,"pushed_at":"2023-03-15T20:27:43.000Z","size":1421,"stargazers_count":481,"open_issues_count":0,"forks_count":92,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-03-29T04:08:58.232Z","etag":null,"topics":["asp-net-core","clean","clean-architecture","cqrs","cqrs-application","cqrs-pattern","ddd","docker","events","eventual-consistency","mongodb","mssql","net-core","netcore","rabbitmq","redis","redis-cache","tdd"],"latest_commit_sha":null,"homepage":"","language":"C#","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/fals.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-07-09T19:08:58.000Z","updated_at":"2025-02-25T19:36:57.000Z","dependencies_parsed_at":"2024-01-13T15:37:14.175Z","dependency_job_id":"faa57910-fcb9-499e-8c59-0a2ff37b6ed3","html_url":"https://github.com/fals/cqrs-clean-eventual-consistency","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fals%2Fcqrs-clean-eventual-consistency","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fals%2Fcqrs-clean-eventual-consistency/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fals%2Fcqrs-clean-eventual-consistency/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fals%2Fcqrs-clean-eventual-consistency/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fals","download_url":"https://codeload.github.com/fals/cqrs-clean-eventual-consistency/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289428,"owners_count":20914464,"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":["asp-net-core","clean","clean-architecture","cqrs","cqrs-application","cqrs-pattern","ddd","docker","events","eventual-consistency","mongodb","mssql","net-core","netcore","rabbitmq","redis","redis-cache","tdd"],"created_at":"2024-09-24T18:51:24.045Z","updated_at":"2025-04-05T05:08:05.096Z","avatar_url":"https://github.com/fals.png","language":"C#","funding_links":[],"categories":["Architectural Style"],"sub_categories":["Clean Architecture"],"readme":"# ![Guaraci](docs/guaraci-icon.png) Clean Architecture CQRS with Derived Data  \n\nCQRS, using Clean Architecture, multiple databases, and Eventual Consistency\n\n## :bookmark_tabs: Detailed information\n\nI also keep more detailed information in my blog\n\n- [X] [CQRS Translated to Clean Architecture](https://blog.fals.io/2018-09-19-cqrs-clean-architecture/)\n    - [X] CQRS Deep dive into Commands\n    - [X] CQRS Queries and Materialization\n    - [X] CQRS Consensus and Consistency\n    - [X] CQRS Distributed chaos, CAP Theorem\n\n\n## :floppy_disk: How do I use it?\n\nYou're going to need the following tools:\n\n* Docker\n* Visual Studio 2019+ or Visual Studio Code\n* .Net 6\n\nExecute in your favorite command line from the `/src` folder\n\n```bash\n$ cd src\n$ docker compose build\n$ docker compose up\n```\n\nOpen your browser and hit the URL to see the OpenApi\n\n`http://localhost:5000/swagger/index.html`\n\nIf you can't run you can hit the health checks to see if a component is down.\n\n`http://localhost:5000/healthcheck`\n\nIf you still have issues, don't run as detached and look the error on the console after executing the docker command.\n\n## :dart: Clean Architecture\n\nHere's the basic architecture of this microservice template:\n\n* Respecting policy rules, with dependencies always pointing inward\n* Separation of technology details from the rest of the system\n* SOLID\n* Single responsibility of each layer\n\n\n![cqrs-clean](docs/cqrs-clean.png)\n\n## :scissors: CQRS\n\nSegregation between Commands and Queries, with isolated databases and different models\n\n![](docs/cqrs_layer_diagram.png)\n\n### :arrow_down: Command Stack\n\nHas direct access to business rules and is responsible for only writing in the application.\n\nBelow you can find a basic interaction between components in the **Command Stack**:\n\n![](docs/create_card_interaction.png)\n\n### :arrow_up: Query Stack\n\nResponsible for providing data to consumers of your application, containing a simplified and more suitable model for reading, with calculated data, aggregated values and materialized structures.\n\nThe image contains the basic interaction between components in the **Query Stack**:\n\n\n\n![](docs/get_card_list_interaction.png)\n\n## :books: DDD\n\nThis example contains a simplified Domain Model, with entities, aggregate roots, value objects and events, which are essential to synchronize the writing with reading database.\n\n## :heavy_check_mark: TDD\n\nThe project contains a well-defined IoC structure that allows you unit test almost every part of this service template, besides technology dependencies.\n\nInside the main layer you're going to find Interfaces that are essential for the application, but with their implementations inside their own layers, what allow Mocking, Stubbing, using test doubles.\n\nThere's a simple example using Mother Object Pattern and Builder to simplify unit tests and keep it maintainable and clean.\n\n## :bar_chart: Data Intensive Microservice\n\nThis microservice template comes with SRP and SOC in mind. Given the own nature of CQRS, you can easily scale this application tuning each stack separately.\n\n## :page_facing_up: Derived Data\n\nHaving multiple data stores makes this system a Derived Data system, which means, you never lose data, you can always rebuild one store from another, for example, if you lose an event which syncs data between the write and read database you can always get this data back from the write database and rebuild the read store.\n\n*Domain Model* is materialized to *Query Models* using view materializer. Keeping this as separed component in the query stack allows fully control to mapped properties and fully testable.\n\n## :envelope: Message Broker\n\nGiven the physical isolation of data stores, **Command Stack** and **Query Stack** must communicate to synchronize data. This is done here using a Message Broker.\n\n![](docs/sync_write_read.jpg)\n\nEvery successful handled command creates an event, which is published into a Message Broker. A synchronization background process subscribes to those events and is responsible for updating the reading database.\n\n## :clock2: Eventual Consistency\n\nEverything comes with some trade offs. The case of CQRS with multiple databases, to maintain high availability and scalability we create inconsistencies between databases.\n\nMore specifically, replicating data between two databases creates an eventual consistency, which in a specific moment in time, given the replication lag they are different, although is a temporary state and it eventually resolves itself.\n\n## :clipboard: References\n\nHere's a list of reliable information used to bring this project to life.\n\n* \u003ca href=\"https://www.amazon.com/Designing-Data-Intensive-Applications-Reliable-Maintainable/dp/1449373321/ref=sr_1_1?ie=UTF8\u0026qid=1537824366\u0026sr=8-1\u0026keywords=designing+data-intensive+applications\" target=\"_blank\"\u003eDesigning Data Intensive Applications\u003c/a\u003e\n\n* \u003ca href=\"https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164\" target=\"_blank\"\u003eClean Architecture, Robert C. Martin\u003c/a\u003e\n\n* \u003ca href=\"https://azure.microsoft.com/en-us/campaigns/cloud-application-architecture-guide/\" target=\"_blank\"\u003eCloud Application Architecture Guide\u003c/a\u003e\n\n* \u003ca href=\"https://www.microsoftpressstore.com/store/microsoft-.net-architecting-applications-for-the-enterprise-9780735685352\" target=\"_blank\"\u003eMicrosoft .NET - Architecting Applications for the Enterprise, 2nd Edition\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffals%2Fcqrs-clean-eventual-consistency","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffals%2Fcqrs-clean-eventual-consistency","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffals%2Fcqrs-clean-eventual-consistency/lists"}