https://github.com/ramonbecker/ms-cqrs
This project implements the Command Query Responsibility Segregation (CQRS) architecture.
https://github.com/ramonbecker/ms-cqrs
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
Last synced: about 2 months ago
JSON representation
This project implements the Command Query Responsibility Segregation (CQRS) architecture.
- Host: GitHub
- URL: https://github.com/ramonbecker/ms-cqrs
- Owner: RamonBecker
- Created: 2024-12-15T13:26:48.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-01-09T20:11:18.000Z (over 1 year ago)
- Last Synced: 2026-01-03T16:19:55.933Z (5 months ago)
- 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
- Language: Java
- Homepage:
- Size: 200 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# CQRS Microservices Architecture with RabbitMQ
## Overview
This project implements the **Command Query Responsibility Segregation (CQRS)** architecture. It is divided into three microservices:
1. **ms-beautique**: Responsible for writing data to the database, handling operations such as insertion, deletion, and updates.
2. **ms-query**: Responsible for reading data from the database, performing query-only operations.
3. **ms-sync**: Handles the synchronization and communication between microservices using **RabbitMQ**.
## Databases
- **PostgreSQL** and **MongoDB** were used for querying data, ensuring an efficient and adaptable approach to the application's data needs.
## Communication
- Communication between microservices is facilitated by **RabbitMQ**, providing robust and effective messaging.
## Deployment
- Services are isolated using **Docker** and **Docker Compose**, ensuring ease of management, scalability, and portability.
## What is CQRS?
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:
### Commands
- 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.
### Queries
- Focused on retrieving data without altering the system state.
- Can be optimized for specific query requirements, often using dedicated read models.
### Benefits of CQRS
1. **Scalability**: Enables independent scaling of read and write operations.
2. **Flexibility**: Allows for optimized complex queries with specialized read models or databases.
3. **Separation of Concerns**: Simplifies code by dividing responsibilities, making the system easier to maintain.
4. **Event Sourcing Support**: Works well with patterns like Event Sourcing, where state changes are represented as events.
### Challenges of CQRS
1. **Increased Complexity**: Adds more components, making implementation and management more challenging.
2. **Synchronization**: Maintaining consistency between read and write models, especially in distributed systems.
3. **Latency**: Propagation of changes to the read models might not be immediate.
---
## RabbitMQ in CQRS
**RabbitMQ** is used as a messaging tool to handle asynchronous communication and decoupling between components in the CQRS architecture.
---
### Broker

---
### How RabbitMQ works

---
### Key Features
#### Decoupling between Commands and Queries
- **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.
#### Synchronization between Write and Read Models
- Changes in the system state are distributed via RabbitMQ events to ensure read models stay synchronized with the write models.
### RabbitMQ Exchange Types
RabbitMQ supports several exchange types for routing messages:
1. **Direct Exchange**
- Routes messages to queues with matching binding keys.
- **Use Case**: Routing by severity levels (e.g., `info`, `error`).

2. **Topic Exchange**
- Routes messages using patterns in routing keys:
- `*` matches a single word.
- `#` matches zero or more words.
- **Use Case**: Flexible publish/subscribe systems.

3. **Fanout Exchange**
- Broadcasts messages to all connected queues, regardless of the routing key.
- **Use Case**: Notifications or global events.

4. **Headers Exchange**
- Routes messages based on headers instead of routing keys.
- **Use Case**: Complex routing based on message attributes.

### Key Advantages of This Implementation
- **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.
---
## Models and Diagrams
The model and operation of the projects, the CQRS architecture and RabbitMQ will be presented below.
### Use case diagram

### Data Model

### Model CQRS

## How CQRS works

## Deployment Instructions
### :rocket: Installation

```
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/
```
## 🔨 Docker
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
```
# API Endpoints Documentation
To access the endpoints you must download the collection file and import it into your postman.
## Ms-Beautique-Query Endpoints
### Customers
1. **List All**: `GET http://localhost:8086/ms-beautique-query/customer`
2. **Find by Name**: `GET http://localhost:8086/ms-beautique-query/customer/name/testname`
3. **Find by Email**: `GET http://localhost:8086/ms-beautique-query/customer/email/testemail`
### Beauty Procedures
1. **List All**: `GET http://localhost:8086/ms-beautique-query/beauty-procedure`
2. **Find by Name**: `GET http://localhost:8086/ms-beautique-query/beauty-procedure/name/testname`
3. **Find by Description**: `GET http://localhost:8086/ms-beautique-query/beauty-procedure/description/testdescription`
### Appointments
1. **Find All**: `GET http://localhost:8086/ms-beautique-query/appointment`
2. **Find by Customer ID**: `GET http://localhost:8086/ms-beautique-query/appointment/customer/1`
3. **Find by Beauty Procedure**: `GET http://localhost:8086/ms-beautique-query/appointment/beauty-procedure/1`
---
## Ms-Command Endpoints
### Customers
1. **Create**: `POST http://localhost:8082/ms-beautique/customer`
```json
{
"name": "name",
"phone": "1231253443",
"email": "teste@teste.com"
}
```
2. **Update**: `PUT http://localhost:8082/ms-beautique/customer`
```json
{
"id": 1,
"name": "name",
"phone": "1231253443",
"email": "teste@teste.com"
}
```
3. **Delete**: `DELETE http://localhost:8082/ms-beautique/customer/{id}`
### Beauty Procedures
1. **Create**: `POST http://localhost:8082/ms-beautique/beauty-procedures`
```json
{
"name": "haircut",
"description": "men's haircut",
"price": 45.00
}
```
2. **Update**: `PATCH http://localhost:8082/ms-beautique/beauty-procedures`
```json
{
"id": 1,
"name": "haircut",
"description": "men's haircut",
"price": 60.00
}
```
3. **Delete**: `DELETE http://localhost:8082/ms-beautique/beauty-procedures/{id}`
### Appointments
1. **Create**: `POST http://localhost:8082/ms-beautique/appointments`
```json
{
"dateTime": "2024-12-28T09:23:00",
"appointmentsOpen": true,
"customer": null,
"beautyProcedure": null
}
```
2. **Update**: `PATCH http://localhost:8082/ms-beautique/appointments`
```json
{
"id": 1,
"dateTime": "2024-12-28T21:00:00",
"appointmentsOpen": true,
"customer": null,
"beautyProcedure": null
}
```
3. **Set Customer**: `PUT http://localhost:8082/ms-beautique/appointments`
```json
{
"id": 1,
"customer": 5,
"beautyProcedure": 5
}
```
4. **Delete**: `DELETE http://localhost:8082/ms-beautique/appointments/{id}`
## RabbitMQ Access Guide
## Prerequisites
Ensure you have the following requirements:
1. RabbitMQ installed and running on your server.
2. Credentials to access the RabbitMQ management interface and message broker.
3. Proper configuration and permissions to access the desired queues and exchanges.
---
## Accessing RabbitMQ Management Interface
### Default URL
The RabbitMQ Management Interface is typically accessible at:
```
http://:15672
```
Replace `` with the IP address or domain name of the RabbitMQ server. If running locally, use `localhost`.
### Login Credentials
Default credentials for RabbitMQ are:
- **Username**: `guest`
- **Password**: `guest`
> Note: The `guest` user can only log in from `localhost`. If you are accessing RabbitMQ remotely, create a new user with the necessary permissions.
---
## Connecting to RabbitMQ via Clients or Applications
### Connection URL
Use the following URL to connect to RabbitMQ:
```
amqp://:@:5672/
```
Replace:
- `` with your RabbitMQ username.
- `` with your RabbitMQ password.
- `` with the RabbitMQ server hostname or IP address.
### Libraries and Tools
- **Java**: Use libraries like [Spring AMQP](https://spring.io/projects/spring-amqp) or [RabbitMQ Java Client](https://www.rabbitmq.com/java-client.html).
## Setting Up Users and Permissions
1. Log in to the RabbitMQ Management Interface.
2. Navigate to the **Admin** tab.
3. Click on **Add a user** and fill in:
- Username
- Password
- Tags (e.g., `administrator` for admin rights or `management` for limited access)
4. Assign permissions to the user:
- Navigate to the **Permissions** section.
- Select the user and assign permissions for vhosts, queues, and exchanges.
---
## Monitoring RabbitMQ
1. Access the Management Interface and check:
- **Queues**: Current messages in queues.
- **Exchanges**: Configured routing logic.
- **Connections**: Active clients.
- **Channels**: Message flow.
2. Use RabbitMQ CLI for monitoring:
```bash
rabbitmqctl list_queues
rabbitmqctl list_exchanges
```
---
For additional details, refer to the [official RabbitMQ documentation](https://www.rabbitmq.com/documentation.html).
## :zap: Technologies
- Java
- Spring Boot
- API REST
- PostgreSQL (Container)
- Docker
- Docker-compose
- MongoDB (Container)
- Shell
- RabbitMQ (Container)
- Spring Data JPA
- Spring AMQP
## :memo: Developed features
- [x] CRUD Customer
- [x] CRUD BeautyProcedures
- [x] CRUD Appointments
## :technologist: Author
By Ramon Becker 👋🏽 Get in touch!
[
](https://github.com/RamonBecker) [
](https://www.linkedin.com/in/ramon-becker-da-silva-96b81b141//)
