|
|
- Screaming Architecture
- Clean Architecture
- Event-Driven Architecture
- Clean Code
- Domain-Driven Design
- SOLID Principles
- Separation of Concerns
- Common Closure Principle
- Common Reuse Principle
- Test Pyramid
- Ambassador Pattern
- Circuit Breaker Pattern
- Mediator Pattern
- Outbox Pattern
- Result Pattern
- Retry Pattern
- Strategy Pattern
- Java
- Spring Boot
- Kong
- Keycloak
- OAuth2
- JWT
- Kafka
- MongoDB
- Debezium
- Redis
- Elastic
- Swagger
- Testcontainers
- Docker
- Kubernetes
-
Full (Run all infrastructure, dependencies, and services)
docker compose --profile full up --detach --build --remove-orphans -
Dev (Run only required infrastructure, dependencies, and services)
-
Windows:
run.ps1 -
Linux:
bash run.shor (chmod +x run.shand./run.sh)
-
-
Kong:
http://localhost:8002 -
Keycloak:
http://localhost:8005Username:adminPassword:password -
Kafka:
http://localhost:9000 -
Mongo:
http://localhost:27018 -
Redis:
http://localhost:6380 -
Logs:
http://localhost:5601/app/management/data/index_management/data_streams -
APM:
http://localhost:5601/app/apm/services
sequenceDiagram
autonumber
participant C as Client
participant AUTH as Auth Service
participant CUST as Customer Service
participant PROD as Product Service
participant ORD as Order Service
participant PAY as Payment Service
participant BUS as Kafka
%% Authentication
C->>AUTH: POST /auth
AUTH-->>C: 200 OK (JWT)
%% Customer Registration
C->>CUST: POST /customers
CUST-->>C: 201 Created (Customer)
%% Product Registration
C->>PROD: POST /products
PROD-->>C: 201 Created (Product)
%% Order Creation
C->>ORD: POST /orders
ORD-->>C: 201 Created (Order)
ORD->>BUS: Publish OrderCreated
BUS-->>PAY: Consume OrderCreated
Note right of PAY: Create payment
rect rgba(46,204,113,0.15)
Note over C,ORD: Payment Approval Flow
C->>PAY: PUT /payments/{id}/approve
PAY-->>C: 204 No Content
PAY->>BUS: Publish PaymentApproved
BUS-->>ORD: Consume PaymentApproved
Note right of ORD: Complete order
end
rect rgba(231,76,60,0.15)
Note over C,ORD: Payment Cancellation Flow
C->>PAY: PUT /payments/{id}/cancel
PAY-->>C: 204 No Content
PAY->>BUS: Publish PaymentCanceled
BUS-->>ORD: Consume PaymentCanceled
Note right of ORD: Cancel order
end
Localhost: http://localhost:8010
Docker: http://localhost:9010
Kong: http://localhost:8000/authservice
| Method | Endpoint | Description |
|---|---|---|
| /auth | Get | |
| /auth | Auth | |
| /users | Save | |
| /users/{id} | Delete |
Localhost: http://localhost:8015
Docker: http://localhost:9015
Kong: http://localhost:8000/configurationservice
| Method | Endpoint | Description |
|---|---|---|
| /configurations | List | |
| /configurations/{id} | Get | |
| /configurations | Create | |
| /configurations/{id} | Delete | |
| /configurations/{id}/value/{value} | Update Value |
Localhost: http://localhost:8020
Docker: http://localhost:9020
Kong: http://localhost:8000/customerservice
| Method | Endpoint | Description |
|---|---|---|
| /customers | List | |
| /customers/{id} | Get | |
| /customers | Create | |
| /customers/{id} | Update | |
| /customers/{id} | Delete |
Localhost: http://localhost:8025
Docker: http://localhost:9025
Kong: http://localhost:8000/productservice
| Method | Endpoint | Description |
|---|---|---|
| /products | List | |
| /products/{id} | Get | |
| /products | Create | |
| /products/{id} | Update | |
| /products/{id} | Delete |
Localhost: http://localhost:8030
Docker: http://localhost:9030
Kong: http://localhost:8000/orderservice
| Method | Endpoint | Description |
|---|---|---|
| /orders | List | |
| /orders/{id} | Get | |
| /orders | Create |
Localhost: http://localhost:8035
Docker: http://localhost:9035
Kong: http://localhost:8000/paymentservice
| Method | Endpoint | Description |
|---|---|---|
| /payments | List | |
| /payments/{id} | Get | |
| /payments/order/{orderId} | Get By Order Id | |
| /payments/{id}/approve | Approve | |
| /payments/{id}/cancel | Cancel |
-
@RequiredArgsConstructor @Service public class ProductCacheService { private static final String ITEM_CACHE = "product"; private static final String LIST_CACHE = "product-list"; private final ProductRepository repository; @Cacheable(cacheNames = LIST_CACHE, sync = true) public List<Product> get() { return repository.findAll(); } @Cacheable(cacheNames = ITEM_CACHE, key = "#id", sync = true) public Optional<Product> get(final UUID id) { return repository.findById(id); } @Caching( put = @CachePut(cacheNames = ITEM_CACHE, key = "#result.id"), evict = @CacheEvict(cacheNames = LIST_CACHE, allEntries = true) ) public Product save(final Product product) { return repository.save(product); } @Caching(evict = { @CacheEvict(cacheNames = ITEM_CACHE, key = "#id"), @CacheEvict(cacheNames = LIST_CACHE, allEntries = true) }) public void delete(final UUID id) { repository.deleteById(id); } @Caching(evict = { @CacheEvict(cacheNames = ITEM_CACHE, allEntries = true), @CacheEvict(cacheNames = LIST_CACHE, allEntries = true) }) public void delete() { repository.deleteAll(); } }