{"id":23519753,"url":"https://github.com/ramonbecker/ms-cqrs","last_synced_at":"2026-04-10T13:31:10.518Z","repository":{"id":268247723,"uuid":"903751375","full_name":"RamonBecker/ms-cqrs","owner":"RamonBecker","description":"This project implements the Command Query Responsibility Segregation (CQRS) architecture. ","archived":false,"fork":false,"pushed_at":"2025-01-09T20:11:18.000Z","size":205,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-03T16:19:55.933Z","etag":null,"topics":["cqrs","cqrs-architecture","cqrs-pattern","cqrs-read","cqrs-write","docker","docker-compose","java","mongodb","postgresql","rabbitmq","rabbitmq-consumer","rabbitmq-producer","rest","restful-api","spring","spring-amqp","spring-boot","spring-data-jpa","webservices"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RamonBecker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-15T13:26:48.000Z","updated_at":"2025-01-09T20:11:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"78d85818-d63d-4e14-b38c-1c19a639df00","html_url":"https://github.com/RamonBecker/ms-cqrs","commit_stats":null,"previous_names":["ramonbecker/ms-cqrs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RamonBecker/ms-cqrs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RamonBecker%2Fms-cqrs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RamonBecker%2Fms-cqrs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RamonBecker%2Fms-cqrs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RamonBecker%2Fms-cqrs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RamonBecker","download_url":"https://codeload.github.com/RamonBecker/ms-cqrs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RamonBecker%2Fms-cqrs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31645180,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T07:40:12.752Z","status":"ssl_error","status_checked_at":"2026-04-10T07:40:11.664Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["cqrs","cqrs-architecture","cqrs-pattern","cqrs-read","cqrs-write","docker","docker-compose","java","mongodb","postgresql","rabbitmq","rabbitmq-consumer","rabbitmq-producer","rest","restful-api","spring","spring-amqp","spring-boot","spring-data-jpa","webservices"],"created_at":"2024-12-25T16:10:22.983Z","updated_at":"2026-04-10T13:31:10.496Z","avatar_url":"https://github.com/RamonBecker.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CQRS Microservices Architecture with RabbitMQ\n\n## Overview\nThis project implements the **Command Query Responsibility Segregation (CQRS)** architecture. It is divided into three microservices:\n\n1. **ms-beautique**: Responsible for writing data to the database, handling operations such as insertion, deletion, and updates.\n2. **ms-query**: Responsible for reading data from the database, performing query-only operations.\n3. **ms-sync**: Handles the synchronization and communication between microservices using **RabbitMQ**.\n\n\n\n## Databases\n- **PostgreSQL** and **MongoDB** were used for querying data, ensuring an efficient and adaptable approach to the application's data needs.\n\n## Communication\n- Communication between microservices is facilitated by **RabbitMQ**, providing robust and effective messaging.\n\n## Deployment\n- Services are isolated using **Docker** and **Docker Compose**, ensuring ease of management, scalability, and portability.\n\n\n\n## What is CQRS?\nThe **Command Query Responsibility Segregation (CQRS)** architecture is an architectural pattern that separates responsibilities for reading and writing operations in a system. Instead of using the same data model and logic for both operations, CQRS divides these into distinct components:\n\n### Commands\n- Responsible for changing the system state.\n- Handles actions such as creating, updating, or deleting data.\n- Follows the principle of not returning data, only confirming the success or failure of operations.\n\n### Queries\n- Focused on retrieving data without altering the system state.\n- Can be optimized for specific query requirements, often using dedicated read models.\n\n### Benefits of CQRS\n1. **Scalability**: Enables independent scaling of read and write operations.\n2. **Flexibility**: Allows for optimized complex queries with specialized read models or databases.\n3. **Separation of Concerns**: Simplifies code by dividing responsibilities, making the system easier to maintain.\n4. **Event Sourcing Support**: Works well with patterns like Event Sourcing, where state changes are represented as events.\n\n### Challenges of CQRS\n1. **Increased Complexity**: Adds more components, making implementation and management more challenging.\n2. **Synchronization**: Maintaining consistency between read and write models, especially in distributed systems.\n3. **Latency**: Propagation of changes to the read models might not be immediate.\n\n---\n\n\n\n## RabbitMQ in CQRS\n**RabbitMQ** is used as a messaging tool to handle asynchronous communication and decoupling between components in the CQRS architecture.\n---\n### Broker\n![Broker CQRS](https://github.com/user-attachments/assets/ad85b476-cf1d-414e-9e61-0ee714ce274a)\n\n---\n### How RabbitMQ works\n\n![Filas RabbitMQ](https://github.com/user-attachments/assets/71abcf13-a275-4409-acf9-c3e4038c6c0f)\n\n\n---\n### Key Features\n\n#### Decoupling between Commands and Queries\n- **Commands (Write)**: Published to RabbitMQ queues, allowing asynchronous processing by specialized services.\n- **Domain Events**: After processing a command, domain events (e.g., `OrderCreated`, `ProductUpdated`) are emitted to inform other services of state changes.\n\n#### Synchronization between Write and Read Models\n- Changes in the system state are distributed via RabbitMQ events to ensure read models stay synchronized with the write models.\n\n### RabbitMQ Exchange Types\nRabbitMQ supports several exchange types for routing messages:\n\n1. **Direct Exchange**\n   - Routes messages to queues with matching binding keys.\n   - **Use Case**: Routing by severity levels (e.g., `info`, `error`).\n\n![_Direct  Exchange](https://github.com/user-attachments/assets/a1e6efac-bd62-4e9e-8a1f-ae7ed044ace2)\n\n\n2. **Topic Exchange**\n   - Routes messages using patterns in routing keys:\n     - `*` matches a single word.\n     - `#` matches zero or more words.\n   - **Use Case**: Flexible publish/subscribe systems.\n\n![Topic  Exchange](https://github.com/user-attachments/assets/8ef43cfb-e1ed-4998-9d77-d5564bab3eaa)\n\n\n3. **Fanout Exchange**\n   - Broadcasts messages to all connected queues, regardless of the routing key.\n   - **Use Case**: Notifications or global events.\n\n![Fanout Exchange](https://github.com/user-attachments/assets/a2ec0de1-af90-48d1-8fd3-5775345932f3)\n\n\n4. **Headers Exchange**\n   - Routes messages based on headers instead of routing keys.\n   - **Use Case**: Complex routing based on message attributes.\n     \n![Header Exchange](https://github.com/user-attachments/assets/588b46da-21f1-4fc4-ae89-62441a9fb8bc)\n\n\n### Key Advantages of This Implementation\n- **Scalable Architecture**: Independent scaling of read and write operations.\n- **Resilient Communication**: RabbitMQ ensures reliable messaging between services.\n- **Flexibility**: PostgreSQL and MongoDB provide tailored solutions for both structured and unstructured data needs.\n- **Portability**: Docker simplifies deployment and portability across environments.\n\n---\n\n\n\n\n## Models and Diagrams\n\nThe model and operation of the projects, the CQRS architecture and RabbitMQ will be presented below.\n\n### Use case diagram\n![Use case diagram](https://github.com/user-attachments/assets/63302697-f07a-46c0-8719-e36eaac39941)\n\n### Data Model\n\n![Data Model](https://github.com/user-attachments/assets/5241396b-d2b1-4abe-beb7-49dc5b0911da)\n\n\n### Model CQRS\n\n\n![Model CQRS](https://github.com/user-attachments/assets/2f6326d2-4581-42c3-bb56-15e5be220b54)\n\n\n\n## How CQRS works\n\n![Func CQRS](https://github.com/user-attachments/assets/7accee2d-1a90-42cb-b0bb-5d478c421ede)\n\n\n## Deployment Instructions\n\n### :rocket: Installation\n\n![](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge\u0026logo=linux\u0026logoColor=black)\n\n\n```\ngit clone https://github.com/RamonBecker/ms-auth.git\n```\n\n![](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge\u0026logo=windows\u0026logoColor=white)\n```\ngit clone https://github.com/RamonBecker/ms-auth.git\nor install github https://desktop.github.com/ \n```\n\n## 🔨 Docker\n\nBefore cloning the project, you will need to install docker on your operating system.\n\nFor windows, enter the following from the link:\n\n```\nhttps://docs.docker.com/desktop/windows/install/\n```\n\nFor linux, follow the procedure below:\n- Update your existing list of packages:\n\n```\nsudo apt update\n```\n\n- Install some prerequisite packages that let apt use packages over HTTPS:\n\n```\nsudo apt install apt-transport-https ca-certificates curl software-properties-common\n\n```\n\n- Add the GPG key to the official Docker repository on your system:\n\n```\ncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -\n```\n- Add the Docker repository to the APT sources:\n\n```\nsudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable\"\n\n```\n\n- Update the package database with Docker packages from the newly added repository:\n\n```\nsudo apt update\n```\n\n- Make sure you are about to install from the Docker repository instead of the default Ubuntu repository:\n\n```\napt-cache policy docker-ce\n```\n\n- Install Docker:\n\n```\nsudo apt install docker-ce\n```\n\n- Check if it is working:\n\n```\nsudo systemctl status docker\n```\n\n- Once you have completed the docker installation, go to the infrastructure folder and run the following commands\n\n```\ndocker compose up --build\ndocker compose up -d\n```\n\n# API Endpoints Documentation\n\nTo access the endpoints you must download the collection file and import it into your postman.\n\n## Ms-Beautique-Query Endpoints\n\n### Customers\n1. **List All**: `GET http://localhost:8086/ms-beautique-query/customer`\n2. **Find by Name**: `GET http://localhost:8086/ms-beautique-query/customer/name/testname`\n3. **Find by Email**: `GET http://localhost:8086/ms-beautique-query/customer/email/testemail`\n\n### Beauty Procedures\n1. **List All**: `GET http://localhost:8086/ms-beautique-query/beauty-procedure`\n2. **Find by Name**: `GET http://localhost:8086/ms-beautique-query/beauty-procedure/name/testname`\n3. **Find by Description**: `GET http://localhost:8086/ms-beautique-query/beauty-procedure/description/testdescription`\n\n### Appointments\n\n1. **Find All**: `GET http://localhost:8086/ms-beautique-query/appointment`\n2. **Find by Customer ID**: `GET http://localhost:8086/ms-beautique-query/appointment/customer/1`\n3. **Find by Beauty Procedure**: `GET http://localhost:8086/ms-beautique-query/appointment/beauty-procedure/1`\n\n---\n\n## Ms-Command Endpoints\n\n### Customers\n1. **Create**: `POST http://localhost:8082/ms-beautique/customer`\n    ```json\n    {\n        \"name\": \"name\",\n        \"phone\": \"1231253443\",\n        \"email\": \"teste@teste.com\"\n    }\n    ```\n\n2. **Update**: `PUT http://localhost:8082/ms-beautique/customer`\n    ```json\n    {\n        \"id\": 1,\n        \"name\": \"name\",\n        \"phone\": \"1231253443\",\n        \"email\": \"teste@teste.com\"\n    }\n    ```\n\n3. **Delete**: `DELETE http://localhost:8082/ms-beautique/customer/{id}`\n\n### Beauty Procedures\n1. **Create**: `POST http://localhost:8082/ms-beautique/beauty-procedures`\n    ```json\n    {\n        \"name\": \"haircut\",\n        \"description\": \"men's haircut\",\n        \"price\": 45.00\n    }\n    ```\n\n2. **Update**: `PATCH http://localhost:8082/ms-beautique/beauty-procedures`\n    ```json\n    {\n        \"id\": 1,\n        \"name\": \"haircut\",\n        \"description\": \"men's haircut\",\n        \"price\": 60.00\n    }\n    ```\n\n3. **Delete**: `DELETE http://localhost:8082/ms-beautique/beauty-procedures/{id}`\n\n### Appointments\n1. **Create**: `POST http://localhost:8082/ms-beautique/appointments`\n    ```json\n    {\n        \"dateTime\": \"2024-12-28T09:23:00\",\n        \"appointmentsOpen\": true,\n        \"customer\": null,\n        \"beautyProcedure\": null\n    }\n    ```\n\n2. **Update**: `PATCH http://localhost:8082/ms-beautique/appointments`\n    ```json\n    {\n        \"id\": 1,\n        \"dateTime\": \"2024-12-28T21:00:00\",\n        \"appointmentsOpen\": true,\n        \"customer\": null,\n        \"beautyProcedure\": null\n    }\n    ```\n\n3. **Set Customer**: `PUT http://localhost:8082/ms-beautique/appointments`\n    ```json\n    {\n        \"id\": 1,\n        \"customer\": 5,\n        \"beautyProcedure\": 5\n    }\n    ```\n\n4. **Delete**: `DELETE http://localhost:8082/ms-beautique/appointments/{id}`\n\n## RabbitMQ Access Guide\n\n## Prerequisites\nEnsure you have the following requirements:\n1. RabbitMQ installed and running on your server.\n2. Credentials to access the RabbitMQ management interface and message broker.\n3. Proper configuration and permissions to access the desired queues and exchanges.\n\n---\n\n## Accessing RabbitMQ Management Interface\n\n### Default URL\nThe RabbitMQ Management Interface is typically accessible at:\n```\nhttp://\u003chostname\u003e:15672\n```\nReplace `\u003chostname\u003e` with the IP address or domain name of the RabbitMQ server. If running locally, use `localhost`.\n\n### Login Credentials\nDefault credentials for RabbitMQ are:\n- **Username**: `guest`\n- **Password**: `guest`\n\n\u003e Note: The `guest` user can only log in from `localhost`. If you are accessing RabbitMQ remotely, create a new user with the necessary permissions.\n\n---\n\n## Connecting to RabbitMQ via Clients or Applications\n\n### Connection URL\nUse the following URL to connect to RabbitMQ:\n```\namqp://\u003cusername\u003e:\u003cpassword\u003e@\u003chostname\u003e:5672/\n```\nReplace:\n- `\u003cusername\u003e` with your RabbitMQ username.\n- `\u003cpassword\u003e` with your RabbitMQ password.\n- `\u003chostname\u003e` with the RabbitMQ server hostname or IP address.\n\n### Libraries and Tools\n- **Java**: Use libraries like [Spring AMQP](https://spring.io/projects/spring-amqp) or [RabbitMQ Java Client](https://www.rabbitmq.com/java-client.html).\n\n\n## Setting Up Users and Permissions\n1. Log in to the RabbitMQ Management Interface.\n2. Navigate to the **Admin** tab.\n3. Click on **Add a user** and fill in:\n   - Username\n   - Password\n   - Tags (e.g., `administrator` for admin rights or `management` for limited access)\n4. Assign permissions to the user:\n   - Navigate to the **Permissions** section.\n   - Select the user and assign permissions for vhosts, queues, and exchanges.\n\n---\n\n## Monitoring RabbitMQ\n1. Access the Management Interface and check:\n   - **Queues**: Current messages in queues.\n   - **Exchanges**: Configured routing logic.\n   - **Connections**: Active clients.\n   - **Channels**: Message flow.\n2. Use RabbitMQ CLI for monitoring:\n   ```bash\n   rabbitmqctl list_queues\n   rabbitmqctl list_exchanges\n   ```\n---\n\nFor additional details, refer to the [official RabbitMQ documentation](https://www.rabbitmq.com/documentation.html).\n\n\n\n## :zap: Technologies\t\n\n- Java\n-  Spring Boot\n- API REST\n- PostgreSQL (Container)\n- Docker\n- Docker-compose\n- MongoDB (Container)\n- Shell\n- RabbitMQ (Container)\n- Spring Data JPA\n- Spring AMQP \n\n## :memo: Developed features\n\n- [x] CRUD Customer\n- [x] CRUD BeautyProcedures\n- [x] CRUD Appointments\n\n## :technologist:\t Author\n\nBy Ramon Becker 👋🏽 Get in touch!\n\n\n\n[\u003cimg src='https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/github.svg' alt='github' height='40'\u003e](https://github.com/RamonBecker)  [\u003cimg src='https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/linkedin.svg' alt='linkedin' height='40'\u003e](https://www.linkedin.com/in/ramon-becker-da-silva-96b81b141//)\n![Gmail Badge](https://img.shields.io/badge/-ramonbecker68@gmail.com-c14438?style=flat-square\u0026logo=Gmail\u0026logoColor=white\u0026link=mailto:ramonbecker68@gmail.com)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framonbecker%2Fms-cqrs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Framonbecker%2Fms-cqrs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Framonbecker%2Fms-cqrs/lists"}