https://github.com/ivan-montes/nano-bestiary
Microservices development for managing your list of preferred mythical beasts. This multimodule Maven project is built with Reactive Programming, Hexagonal Arch, CQRS, Event Sourcing, and Kafka for synchronizing databases. RSocket for communication between microservices and Redis to store relevant information from other components.
https://github.com/ivan-montes/nano-bestiary
cqrs event-sourcing hexagonal-architecture java jwt kafka reactive redis rsocket spring webflux
Last synced: 3 months ago
JSON representation
Microservices development for managing your list of preferred mythical beasts. This multimodule Maven project is built with Reactive Programming, Hexagonal Arch, CQRS, Event Sourcing, and Kafka for synchronizing databases. RSocket for communication between microservices and Redis to store relevant information from other components.
- Host: GitHub
- URL: https://github.com/ivan-montes/nano-bestiary
- Owner: Ivan-Montes
- License: gpl-3.0
- Created: 2024-11-25T06:41:20.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-24T11:38:24.000Z (over 1 year ago)
- Last Synced: 2025-03-24T12:31:56.369Z (over 1 year ago)
- Topics: cqrs, event-sourcing, hexagonal-architecture, java, jwt, kafka, reactive, redis, rsocket, spring, webflux
- Language: Java
- Homepage:
- Size: 593 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# nano-bestiary
Microservices development for managing your list of preferred mythical beasts. This multimodule Maven project is built with Reactive Programming, Hexagonal Arch, CQRS, Event Sourcing, and Kafka for synchronizing databases. [RSocket](https://rsocket.io/) for communication between microservices and Redis to store relevant information from other components.
**Components**
- [Kafka](https://kafka.apache.org/) [9092] + [9093]
- [Kafka-UI](https://docs.kafka-ui.provectus.io/) [8081]
- Eureka server as service registry and discovery service [8761]
- API Gateway with centralized [OpenApi Swagger-UI](https://swagger.io/) [8080]
- REST API ms-area with [OpenApi Swagger-UI](https://swagger.io/) [0]
- REST API ms-creature with [OpenApi Swagger-UI](https://swagger.io/) [0]
- REST API oauth2-server with [OpenApi Swagger-UI](https://swagger.io/) working as JWT Token Authorization Server [9000]
```mermaid
graph BT
subgraph KafkaUI
Kafka-UI
end
subgraph Kafka
Kafka-Server
end
subgraph oauth2-server
oauth2server{{JWT Authorization Server}}
end
subgraph ms-area
A{{Area}}
end
subgraph ms-area-db["Databases for ms-area"]
direction RL
A1[(Sql Read Db)]
A2[(NoSql Write Db)]
A3[(Redis Backup Db)]
end
subgraph ms-creature
C{{Creature}}
end
subgraph ms-creature-db["Databases for ms-creature"]
direction RL
C1[(Sql Read Db)]
C2[(NoSql Write Db)]
C3[(Redis Backup Db)]
end
ms-area-db <--> ms-area
ms-creature-db <--> ms-creature
A1 <-. Synchro .-> A2
C1 <-. Synchro .-> C2
ms-area <-->|Publish-Subscriber| Kafka
ms-creature <-->|Publish-Subscriber| Kafka
ms-area <-.->| | oauth2-server
ms-creature <-.->| | oauth2-server
KafkaUI <--> | | Kafka
classDef canvas_basic fill:#82C0CC,stroke:#333;
classDef ms_basic fill:#FFB703,stroke:#333;
classDef db_basic fill:#FD9E02,stroke:#333;
classDef redis_basic fill:#FB8500,stroke:#333
class ms-area-db,ms-creature-db canvas_basic
class A,C,Kafka-UI,oauth2server,Kafka-Server ms_basic
class A1,A2,C1,C2, db_basic
class A3,C3 redis_basic
class ms-area,ms-creature,oauth2-server,Kafka,KafkaUI canvas_basic
```
## Table of contents
- [Installation](#installation)
- [Usage](#usage)
- [It's not a bug, it's a feature](#features)
- [Maintainers](#maintainers)
- [License](#license)
## Installation
1. First of all clone or download the project.
1. Inside the main folder, you could find two docker-compose yaml files.
1. From there use the command line to start the project in dev or production mode
```
**Developer mode**
docker-compose -f docker-compose-dev.yml up -d
**Production mode**
docker-compose -f docker-compose-prod.yml up -d
```
The dev environment is ready for using with your IDE. The microservice attempts to communicate with Kafka using the local host. In production, it uses the archive Dockerfile to build an image of the project, so you wont need the IDE.
4. You could stop the project and free resources with any of these orders
```
**Developer mode**
docker-compose -f docker-compose-dev.yml down --rmi local -v
**Production mode**
docker-compose -f docker-compose-prod.yml down --rmi local -v
```
## Usage
First of all, please visit the centralized REST API documentation on the Api-Gateway server. You can change the selection on the upper dropdown menu.
http://localhost:8080/swagger-ui.html
In this context, unexpected behavior may occur due to the different network settings when using Swagger requests directly from Api-Gateway centralized Swagger-UI. To prevent some of these issues, CORS and CSRF have been disabled in Spring Security settings. Alternatively if you want use the Swagger-UI dashboard for REST operations, it is recommended to call the microservice directly:
http://localhost:${port}/swagger-ui.html.
API Rest Endpoints have dynamic ports but Api Gateway responds on 8080 port, so you could use a program like [SoapUI](https://www.soapui.org/) or [curl](https://curl.se/) and call them with the following nomenclature http://${hostname}:8080/api/v1/${entity}. For instance:
```
** Get a List of Area entities **
curl -v http://localhost:8080/api/v1/areas
** Get a Creature according to an Id **
curl -v http://localhost:8080/api/v1/creatures/22000000-0000-0000-0000-000000000003
** Create Area **
curl -v -H "Content-Type: application/json" -d '{"areaName":"Delfos"}' http://localhost:8080/api/v1/areas
** Update Creature **
curl -v -X "PUT" -H "Content-Type: application/json" -d '{"creatureName":"Harpy", "creatureDescription":"half-human and half-bird", "areaId":"11000000-0000-0000-0000-000000000001"}' http://localhost:8080/api/v1/creatures/22000000-0000-0000-0000-000000000008
** Delete a Creature according to an Id **
curl -v -X "DELETE" http://localhost:8080/api/v1/creatures/22000000-0000-0000-0000-000000000005
```
The initial data load is performed by the kafka-data-init microservice. It uses Kafka to publish events, which the other microservices then use to update their databases.
[Kafka-UI](https://docs.kafka-ui.provectus.io/) allow you to check your [Kafka](https://kafka.apache.org/) server using a practical dashboard, so visit the following url:
http://localhost:8081
A good way for checking the JWT generation and validation flow, is reading [this](https://adictosaltrabajo.com/2023/06/29/securizacion-aplicacion-oauth-2-spring-authorization-server-spring-resource-server/) and following these steps:
- First you should register an user using the method POST and the URL `http://localhost:9000/register`. Here is an example of the info you need to send:
```
{
"name":"Marco",
"lastname":"Polo",
"email":"marcopolo@venice.it",
"password":"passpasspass"
}
```
- Next, since form-based login authorization is active, we need to use a browser. Navigate to `http://localhost:9000/login` and use the credentials you have just created. Ignore any NoResourceFoundException error.
- Then we will request the authorization code with the same browser. The authorization server will respond with a code, which the client can exchange for tokens over a secure channel.
```
http://localhost:9000/oauth2/authorize
?client_id=client
&redirect_uri=http://localhost:9000/callback
&scope=openid
&response_type=code
&response_mode=query
&state=k13gsri3gw
&nonce=njumydikqj
```
- We use the POST method to request our JWT token sending the authorization code and the rest of parameters

- Now we can use the retrieved JWT token to reach the unique protected URL in the rest of microservices at *http://{host}:{port}/actuator/metrics*
This project has my own profile of [SoapUI](https://www.soapui.org/) with the endpoints configured. Everything is in the file Proy-nano-bestiary-soapui-project.xml at the root folder.
If you want to test the project in a Kubernetes environment, you can use the contents of k8s-manifest folder. The manifests are configured for development profile, so you need your IDE to deploy the microservice infrastructure. You can run all manifest files with:
kubectl -apply ./k8s-manifest
## Features
#### :arrow_forward: Unit testing for business logic classes using Test Containers for Repositories
#### :arrow_forward: Hexagonal Architecture and CQRS with independent databases
#### :arrow_forward: Redis DB for each microservice works as caches to store ID references for other REST APIs
#### :arrow_forward: Event Sourcing for persisting as an ordered sequence of events
#### :arrow_forward: Use of RSocket for request communication between microservices
## Maintainers
Just me, [Iván](https://github.com/Ivan-Montes) :sweat_smile:
## License
[GPLv3 license](https://choosealicense.com/licenses/gpl-3.0/)
---
[](https://www.java.com/es/)
[](https://https://maven.apache.org/)
[](https://spring.io)
[](https://github.com)
[](https://https://eclipse.org/)
[](https://www.sonarsource.com/products/sonarqube/downloads/)
[](https://www.docker.com/)
[](https://kafka.apache.org/)
[](https://choosealicense.com/licenses/gpl-3.0/)