This project implements the Command Query Responsibility Segregation (CQRS) architecture. It is divided into three microservices:
- ms-beautique: Responsible for writing data to the database, handling operations such as insertion, deletion, and updates.
- ms-query: Responsible for reading data from the database, performing query-only operations.
- ms-sync: Handles the synchronization and communication between microservices using RabbitMQ.
- PostgreSQL and MongoDB were used for querying data, ensuring an efficient and adaptable approach to the application's data needs.
- Communication between microservices is facilitated by RabbitMQ, providing robust and effective messaging.
- Services are isolated using Docker and Docker Compose, ensuring ease of management, scalability, and portability.
The 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:
- Responsible for changing the system state.
- Handles actions such as creating, updating, or deleting data.
- Follows the principle of not returning data, only confirming the success or failure of operations.
- Focused on retrieving data without altering the system state.
- Can be optimized for specific query requirements, often using dedicated read models.
- Scalability: Enables independent scaling of read and write operations.
- Flexibility: Allows for optimized complex queries with specialized read models or databases.
- Separation of Concerns: Simplifies code by dividing responsibilities, making the system easier to maintain.
- Event Sourcing Support: Works well with patterns like Event Sourcing, where state changes are represented as events.
- Increased Complexity: Adds more components, making implementation and management more challenging.
- Synchronization: Maintaining consistency between read and write models, especially in distributed systems.
- Latency: Propagation of changes to the read models might not be immediate.
RabbitMQ is used as a messaging tool to handle asynchronous communication and decoupling between components in the CQRS architecture.
- Commands (Write): Published to RabbitMQ queues, allowing asynchronous processing by specialized services.
- Domain Events: After processing a command, domain events (e.g.,
OrderCreated
,ProductUpdated
) are emitted to inform other services of state changes.
- Changes in the system state are distributed via RabbitMQ events to ensure read models stay synchronized with the write models.
RabbitMQ supports several exchange types for routing messages:
- Direct Exchange
- Routes messages to queues with matching binding keys.
- Use Case: Routing by severity levels (e.g.,
info
,error
).
- Topic Exchange
- Routes messages using patterns in routing keys:
*
matches a single word.#
matches zero or more words.
- Use Case: Flexible publish/subscribe systems.
- Routes messages using patterns in routing keys:
- Fanout Exchange
- Broadcasts messages to all connected queues, regardless of the routing key.
- Use Case: Notifications or global events.
- Headers Exchange
- Routes messages based on headers instead of routing keys.
- Use Case: Complex routing based on message attributes.
- Scalable Architecture: Independent scaling of read and write operations.
- Resilient Communication: RabbitMQ ensures reliable messaging between services.
- Flexibility: PostgreSQL and MongoDB provide tailored solutions for both structured and unstructured data needs.
- Portability: Docker simplifies deployment and portability across environments.
The model and operation of the projects, the CQRS architecture and RabbitMQ will be presented below.
git clone https://github.com/RamonBecker/ms-auth.git
git clone https://github.com/RamonBecker/ms-auth.git
or install github https://desktop.github.com/
Before cloning the project, you will need to install docker on your operating system.
For windows, enter the following from the link:
https://docs.docker.com/desktop/windows/install/
For linux, follow the procedure below:
- Update your existing list of packages:
sudo apt update
- Install some prerequisite packages that let apt use packages over HTTPS:
sudo apt install apt-transport-https ca-certificates curl software-properties-common
- Add the GPG key to the official Docker repository on your system:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- Add the Docker repository to the APT sources:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
- Update the package database with Docker packages from the newly added repository:
sudo apt update
- Make sure you are about to install from the Docker repository instead of the default Ubuntu repository:
apt-cache policy docker-ce
- Install Docker:
sudo apt install docker-ce
- Check if it is working:
sudo systemctl status docker
- Once you have completed the docker installation, go to the infrastructure folder and run the following commands
docker compose up --build
docker compose up -d
To access the endpoints you must download the collection file and import it into your postman.
- List All:
GET http://localhost:8086/ms-beautique-query/customer
- Find by Name:
GET http://localhost:8086/ms-beautique-query/customer/name/testname
- Find by Email:
GET http://localhost:8086/ms-beautique-query/customer/email/testemail
- List All:
GET http://localhost:8086/ms-beautique-query/beauty-procedure
- Find by Name:
GET http://localhost:8086/ms-beautique-query/beauty-procedure/name/testname
- Find by Description:
GET http://localhost:8086/ms-beautique-query/beauty-procedure/description/testdescription
- Find All:
GET http://localhost:8086/ms-beautique-query/appointment
- Find by Customer ID:
GET http://localhost:8086/ms-beautique-query/appointment/customer/1
- Find by Beauty Procedure:
GET http://localhost:8086/ms-beautique-query/appointment/beauty-procedure/1
-
Create:
POST http://localhost:8082/ms-beautique/customer
{ "name": "name", "phone": "1231253443", "email": "teste@teste.com" }
-
Update:
PUT http://localhost:8082/ms-beautique/customer
{ "id": 1, "name": "name", "phone": "1231253443", "email": "teste@teste.com" }
-
Delete:
DELETE http://localhost:8082/ms-beautique/customer/{id}
-
Create:
POST http://localhost:8082/ms-beautique/beauty-procedures
{ "name": "haircut", "description": "men's haircut", "price": 45.00 }
-
Update:
PATCH http://localhost:8082/ms-beautique/beauty-procedures
{ "id": 1, "name": "haircut", "description": "men's haircut", "price": 60.00 }
-
Delete:
DELETE http://localhost:8082/ms-beautique/beauty-procedures/{id}
-
Create:
POST http://localhost:8082/ms-beautique/appointments
{ "dateTime": "2024-12-28T09:23:00", "appointmentsOpen": true, "customer": null, "beautyProcedure": null }
-
Update:
PATCH http://localhost:8082/ms-beautique/appointments
{ "id": 1, "dateTime": "2024-12-28T21:00:00", "appointmentsOpen": true, "customer": null, "beautyProcedure": null }
-
Set Customer:
PUT http://localhost:8082/ms-beautique/appointments
{ "id": 1, "customer": 5, "beautyProcedure": 5 }
-
Delete:
DELETE http://localhost:8082/ms-beautique/appointments/{id}
Ensure you have the following requirements:
- RabbitMQ installed and running on your server.
- Credentials to access the RabbitMQ management interface and message broker.
- Proper configuration and permissions to access the desired queues and exchanges.
The RabbitMQ Management Interface is typically accessible at:
http://<hostname>:15672
Replace <hostname>
with the IP address or domain name of the RabbitMQ server. If running locally, use localhost
.
Default credentials for RabbitMQ are:
- Username:
guest
- Password:
guest
Note: The
guest
user can only log in fromlocalhost
. If you are accessing RabbitMQ remotely, create a new user with the necessary permissions.
Use the following URL to connect to RabbitMQ:
amqp://<username>:<password>@<hostname>:5672/
Replace:
<username>
with your RabbitMQ username.<password>
with your RabbitMQ password.<hostname>
with the RabbitMQ server hostname or IP address.
- Java: Use libraries like Spring AMQP or RabbitMQ Java Client.
- Log in to the RabbitMQ Management Interface.
- Navigate to the Admin tab.
- Click on Add a user and fill in:
- Username
- Password
- Tags (e.g.,
administrator
for admin rights ormanagement
for limited access)
- Assign permissions to the user:
- Navigate to the Permissions section.
- Select the user and assign permissions for vhosts, queues, and exchanges.
- Access the Management Interface and check:
- Queues: Current messages in queues.
- Exchanges: Configured routing logic.
- Connections: Active clients.
- Channels: Message flow.
- Use RabbitMQ CLI for monitoring:
rabbitmqctl list_queues rabbitmqctl list_exchanges
For additional details, refer to the official RabbitMQ documentation.
- Java
- Spring Boot
- API REST
- PostgreSQL (Container)
- Docker
- Docker-compose
- MongoDB (Container)
- Shell
- RabbitMQ (Container)
- Spring Data JPA
- Spring AMQP
- CRUD Customer
- CRUD BeautyProcedures
- CRUD Appointments
By Ramon Becker ππ½ Get in touch!