Skip to content

This project implements the Command Query Responsibility Segregation (CQRS) architecture.

Notifications You must be signed in to change notification settings

RamonBecker/ms-cqrs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

50 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

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

Broker CQRS


How RabbitMQ works

Filas RabbitMQ


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).

_Direct  Exchange

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

Topic  Exchange

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

Fanout Exchange

  1. Headers Exchange
    • Routes messages based on headers instead of routing keys.
    • Use Case: Complex routing based on message attributes.

Header Exchange

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

Use case diagram

Data Model

Data Model

Model CQRS

Model CQRS

How CQRS works

Func CQRS

Deployment Instructions

πŸš€ 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

    {
        "name": "name",
        "phone": "1231253443",
        "email": "teste@teste.com"
    }
  2. Update: PUT http://localhost:8082/ms-beautique/customer

    {
        "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

    {
        "name": "haircut",
        "description": "men's haircut",
        "price": 45.00
    }
  2. Update: PATCH http://localhost:8082/ms-beautique/beauty-procedures

    {
        "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

    {
        "dateTime": "2024-12-28T09:23:00",
        "appointmentsOpen": true,
        "customer": null,
        "beautyProcedure": null
    }
  2. Update: PATCH http://localhost:8082/ms-beautique/appointments

    {
        "id": 1,
        "dateTime": "2024-12-28T21:00:00",
        "appointmentsOpen": true,
        "customer": null,
        "beautyProcedure": null
    }
  3. Set Customer: PUT http://localhost:8082/ms-beautique/appointments

    {
        "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://<hostname>:15672

Replace <hostname> 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://<username>:<password>@<hostname>:5672/

Replace:

  • <username> with your RabbitMQ username.
  • <password> with your RabbitMQ password.
  • <hostname> with the RabbitMQ server hostname or IP address.

Libraries and Tools

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:
    rabbitmqctl list_queues
    rabbitmqctl list_exchanges

For additional details, refer to the official RabbitMQ documentation.

⚑ Technologies

  • Java
  • Spring Boot
  • API REST
  • PostgreSQL (Container)
  • Docker
  • Docker-compose
  • MongoDB (Container)
  • Shell
  • RabbitMQ (Container)
  • Spring Data JPA
  • Spring AMQP

πŸ“ Developed features

  • CRUD Customer
  • CRUD BeautyProcedures
  • CRUD Appointments

πŸ§‘β€πŸ’» Author

By Ramon Becker πŸ‘‹πŸ½ Get in touch!

github linkedin Gmail Badge