A powerful Node.js CLI for generating Spring Boot projects with modular architecture that enables efficient monolith-first development with seamless transition to microservices
npm install eva4jbash
Create a complete project
eva4j create my-ecommerce
cd my-ecommerce
Add a module
eva4j add module product
Generate full CRUD from YAML
eva4j g entities product
๐ Done! You have:
โ
Domain entities with business logic
โ
JPA repositories and mappers
โ
CQRS commands and queries
โ
REST API with pagination
โ
Complete hexagonal architecture
`
---
๐ Why eva4j?
$3
Building Spring Boot applications with proper architecture requires:
- โ Hours setting up project structure
- โ Repetitive code for CRUD operations
- โ Manual wiring of layers (domain, application, infrastructure)
- โ Complex microservices infrastructure from day one
- โ Risk of architectural inconsistencies
$3
eva4j provides:
- โ
Project in seconds - Complete structure with one command
- โ
YAML-driven development - Define domain model, generate 90% of code
- โ
Automatic layer wiring - Domain, application, infrastructure pre-connected
- โ
Modular monolith first - Simple development, microservices ready
- โ
Architectural consistency - Same patterns across all modules
---
๐ฏ Key Benefits & Impact
$3
| Task | Without eva4j | With eva4j | Time Saved |
|------|---------------|------------|------------|
| Project setup | 2-4 hours | 30 seconds | 99% |
| Module creation | 1-2 hours | 15 seconds | 99% |
| Entity + CRUD | 3-6 hours | 1 minute | 98% |
| HTTP integration | 1-2 hours | 30 seconds | 99% |
| Kafka setup | 2-3 hours | 30 seconds | 99% |
Total saved per module: 7-15 hours โ Invest in business logic instead!
$3
- โ
Clean/Hexagonal Architecture - Enforced by design
- โ
CQRS Pattern - Write and read operations properly separated
- โ
Domain-Driven Design - Entities, Value Objects, Aggregates
- โ
Best Practices - Industry-standard patterns built-in
- โ
No Architectural Drift - All modules follow same structure
$3
- โ
Simple Learning Curve - YAML + CLI commands
- โ
Interactive Prompts - Guided project creation
- โ
Clear Documentation - Every command fully documented
- โ
Rich Examples - 10+ YAML examples included
- โ
Fast Feedback - Generate, run, test in seconds
$3
#### Start Simple (Modular Monolith)
- ๐ Single repository - All code in one place
- ๐ฅ๏ธ Single application - Deploy and debug easily
- ๐ Simple debugging - Breakpoints work across modules
- โก Fast startup - Seconds, not minutes
- ๐งช Integrated testing - Test module interactions without Docker
#### Scale When Needed (Microservices)
- ๐ Extract modules - One command to microservice
- ๐ Zero rewrite - Same code structure
- ๐ฆ Independent deployment - Deploy modules separately
- ๐ฏ Gradual migration - Extract only what you need
- ๐๏ธ Same architecture - Familiar structure everywhere
---
๐ Real-World Impact
$3
Traditional Approach:
`
Week 1-2: Project setup, architecture decisions
Week 3-4: First module implementation
Week 5-6: Second module, refactor patterns
Week 7-8: Third module, stabilize architecture
Week 9+: Business logic finally starts
`
With eva4j:
`
Day 1: Project setup, 3 modules created, CRUD working
Week 1: Business logic implementation
Week 2: Testing and refinement
Week 3+: More features, not more infrastructure
`
Result: Ship in 1/3 of the time while maintaining higher quality standards.
---
๐ก Development Philosophy
$3
You don't need from day one:
- โ Multiple services running
- โ Distributed databases
- โ Service mesh
- โ Complex orchestration
- โ Microservices overhead
Instead, you get:
- โ
Single application - Simple to develop and debug
- โ
Module boundaries - Enforced by Spring Modulith
- โ
Clean architecture - Ready for extraction
- โ
Fast iteration - Change multiple modules instantly
- โ
Microservices ready - Extract when business requires it
$3
Reduce setup time from days to minutes, maintain architectural consistency, and scale from rapid development to distributed production when actually needed.
๐ฏ Philosophy: Modular Monolith to Microservices
Eva4j follows a pragmatic approach to microservices architecture:
$3
- Single repository with multiple domain modules
- Fast development with shared codebase and immediate refactoring
- Easy testing - run entire system locally
- Simplified debugging - single application to run
- Reduced complexity - no distributed system concerns
- Spring Modulith ensures module boundaries and prevents coupling
$3
- Detach modules into independent microservices with one command
- Deploy independently to production environments
- Scale individually based on load requirements
- Maintain separately with isolated teams
- Same codebase structure - familiar architecture
$3
โ
Faster time-to-market - develop as monolith, deploy as microservices
โ
Lower operational complexity during development
โ
Enforced boundaries - Spring Modulith validates module independence
โ
Zero code rewrite - detached services maintain the same structure
โ
Gradual migration - extract modules to microservices when needed
---
๐ Features
- ๐ฆ Modular Architecture - Package-by-feature with Spring Modulith
- ๐๏ธ Clean/Hexagonal Architecture - Ports & Adapters pattern
- โก CQRS Pattern - Command/Query separation for use cases
- ๐ Event-Driven - Kafka integration for async communication
- ๐ HTTP Clients - Spring Cloud OpenFeign for external services
- ๐ฏ Module Detachment - Extract modules to microservices
- ๐๏ธ Multi-Database - PostgreSQL, MySQL, or H2
- ๐ง Multi-Environment - local, develop, test, production configs
- โจ Interactive CLI - Beautiful prompts and validations
- ๐ Auto Documentation - Spring Modulith docs generation
---
๐ฅ Installation
`bash
npm install -g eva4j
`
Or for local development:
`bash
npm install
npm link
`
---
๐ Complete Documentation
$3
All commands are fully documented with examples, use cases, and best practices:
๐ Complete Commands Index - Full documentation hub
#### Quick Links to Most Used Commands
| Command | Purpose | Documentation |
|---------|---------|---------------|
| create | Create new project | ๐ CREATE.md |
| add module | Add domain module | ๐ ADD_MODULE.md |
| g entities | Generate from YAML | ๐ GENERATE_ENTITIES.md |
| g usecase | Create use case | ๐ GENERATE_USECASE.md |
| g resource | Generate REST API | ๐ GENERATE_RESOURCE.md |
| g http | HTTP client | ๐ GENERATE_HTTP_EXCHANGE.md |
| g kafka-event | Kafka events | ๐ GENERATE_KAFKA_EVENT.md |
| detach | Extract microservice | ๐ DETACH.md |
$3
- DOMAIN_YAML_GUIDE.md - Complete YAML syntax reference
- QUICK_REFERENCE.md - Command cheat sheet
- examples/ - 10+ YAML examples for different scenarios
---
๐ Commands Documentation
Eva4j provides a comprehensive set of commands for different stages of development. Each command has detailed documentation with examples and best practices.
$3
| Command | Description | Documentation |
|---------|-------------|---------------|
| create | Create a new Spring Boot project with modular architecture | ๐ CREATE.md |
| add module | Add a new domain module with hexagonal architecture | ๐ ADD_MODULE.md |
| detach | Extract a module into an independent microservice | ๐ DETACH.md |
$3
| Command | Description | Documentation |
|---------|-------------|---------------|
| generate entities (g entities) | Generate complete domain model from YAML | ๐ GENERATE_ENTITIES.md |
| generate usecase (g usecase) | Create CQRS commands or queries | ๐ GENERATE_USECASE.md |
| generate resource (g resource) | Generate REST controller with CRUD endpoints | ๐ GENERATE_RESOURCE.md |
| generate record (g record) | Create Java Record for DTOs | ๐ GENERATE_RECORD.md |
$3
| Command | Description | Documentation |
|---------|-------------|---------------|
| generate http-exchange (g http) | Create HTTP client with OpenFeign | ๐ GENERATE_HTTP_EXCHANGE.md |
| generate kafka-event (g kafka-event) | Setup Kafka event publishing | ๐ GENERATE_KAFKA_EVENT.md |
| generate kafka-listener (g kafka-listener) | Create Kafka event consumer | Coming soon |
| add kafka-client | Add Kafka dependencies to module | Coming soon |
$3
`bash
1. Create project
eva4j create my-ecommerce
cd my-ecommerce
2. Start development services
docker-compose up -d
3. Add modules
eva4j add module product
eva4j add module order
eva4j add module customer
4. Generate entities from YAML
eva4j g entities product
5. Run application
./gradlew bootRun
`
$3
For faster development, most generate commands have short aliases:
`bash
eva4j g entities # generate entities
eva4j g usecase # generate usecase
eva4j g resource # generate resource
eva4j g record # generate record
eva4j g http # generate http-exchange
eva4j g kafka-event # generate kafka-event
eva4j g kafka-listener # generate kafka-listener
`
---
๐ Detailed Command Reference
$3
Initialize a new Spring Boot project with modular architecture.
`bash
eva4j create
`
Creates a production-ready Spring Boot project with:
- โ
Modular architecture (Spring Modulith)
- โ
Multi-environment configuration (local, dev, test, prod)
- โ
Docker Compose with database and Kafka
- โ
Gradle build with all necessary dependencies
- โ
Hexagonal architecture structure
๐ Full Documentation
---
$3
Add a domain module following hexagonal architecture.
`bash
eva4j add module
`
Generates a complete module with:
- โ
Domain layer (entities, value objects, repositories)
- โ
Application layer (commands, queries, handlers, DTOs)
- โ
Infrastructure layer (JPA, REST controllers)
- โ
CQRS pattern ready
- โ
Spring Modulith boundaries validated
๐ Full Documentation
---
$3
Generate complete domain implementation from YAML definition.
`bash
eva4j generate entities
eva4j g entities # Short alias
`
Creates from a YAML file:
- โ
Domain entities and value objects
- โ
JPA entities and repositories
- โ
CRUD commands and queries
- โ
Command/Query handlers
- โ
DTOs and mappers
- โ
REST controller
๐ Full Documentation
Example YAML: See examples/ directory for complete examples.
---
$3
For complete documentation on all commands, see:
- generate usecase - Create individual CQRS use cases
- generate resource - Generate REST controllers
- generate record - Create Java Records
- generate http-exchange - HTTP client integration
- generate kafka-event - Kafka event publishing
- detach - Extract module to microservice
---
๐ฏ Common Workflows
$3
`bash
1. Add module
eva4j add module product
2. Create YAML definition
Edit examples/product.yaml
3. Generate entities
eva4j g entities product
4. Run and test
./gradlew bootRun
`
$3
`bash
Generate additional commands
eva4j g usecase UpdateProductPrice --type command
eva4j g usecase DeactivateProduct --type command
Generate custom queries
eva4j g usecase SearchProductsByCategory --type query
eva4j g usecase GetLowStockProducts --type query
`
$3
`bash
Create HTTP client
eva4j g http PaymentGateway
Configure in application.yaml
Implement client methods
Use in domain through ports
`
$3
`bash
Publish events
eva4j g kafka-event OrderCreated
Consume events in another module
eva4j g kafka-listener OrderCreated
`
$3
`bash
When module is mature and needs independence
eva4j detach order
Result: order-service/ as standalone application
`
---
๐ Additional Resources
- DOMAIN_YAML_GUIDE.md - Complete YAML syntax reference
- QUICK_REFERENCE.md - Command cheat sheet
- examples/ - YAML examples for different scenarios
---
$3
For backward compatibility, here's the old reference format:
$3
Install Kafka dependencies and configuration.
`bash
eva4j add kafka-client
`
What it does:
- Adds spring-kafka dependencies to build.gradle
- Creates kafka.yaml configuration for all environments
- Generates KafkaConfig.java in shared module
- Updates application-*.yaml to import kafka.yaml
Generated Configuration:
`yaml
parameters/local/kafka.yaml
spring.kafka:
bootstrap-servers: localhost:9092
consumer:
group-id: ${spring.application.name}
topics:
# Topics will be added by generate kafka-event
`
Example:
`bash
eva4j add kafka-client
`
---
$3
Create a use case (command or query) following CQRS pattern.
`bash
eva4j generate usecase [usecase-name]
eva4j g usecase [usecase-name]
`
Interactive Prompts:
- Use case name (if not provided)
- Type: Command (write) or Query (read)
Command Pattern (write operations):
`java
// CreateUserCommand.java
public record CreateUserCommand(String name, String email) {}
// CreateUserCommandHandler.java
@ApplicationComponent
public class CreateUserCommandHandler {
public UserResponseDto handle(CreateUserCommand command) {
// Business logic
}
}
`
Query Pattern (read operations):
`java
// FindUserByIdQuery.java
public record FindUserByIdQuery(UUID id) {}
// FindUserByIdQueryHandler.java
@ApplicationComponent
public class FindUserByIdQueryHandler {
public UserResponseDto handle(FindUserByIdQuery query) {
// Business logic
}
}
// UserResponseDto.java
public record UserResponseDto(UUID id, String name, String email) {}
`
Examples:
`bash
eva4j g usecase user create-user # Command
eva4j g usecase user find-user-by-id # Query
eva4j g usecase product update-stock # Command
`
---
$3
Generate complete REST resource with full CRUD operations.
`bash
eva4j generate resource
eva4j g resource
`
Interactive Prompts:
- Resource name (default: module name)
- API version (default: v1)
What it generates:
- 5 Use Cases (Create, Update, Delete, FindById, FindAll)
- Response DTO
- REST Controller with 5 endpoints
Generated Endpoints:
`java
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@PostMapping // POST /api/v1/users
@GetMapping("/{id}") // GET /api/v1/users/{id}
@GetMapping // GET /api/v1/users
@PutMapping("/{id}") // PUT /api/v1/users/{id}
@DeleteMapping("/{id}") // DELETE /api/v1/users/{id}
}
`
Example:
`bash
eva4j g resource user
eva4j g resource product
`
---
$3
Create HTTP client adapter using Spring Cloud OpenFeign.
`bash
eva4j generate http-exchange [port-name]
eva4j g http-exchange [port-name]
`
Interactive Prompts:
- Port name (if not provided)
- Base URL of remote service
Generated Structure:
`java
// application/ports/ProductService.java
public interface ProductService {
ProductDto getProduct(UUID id);
}
// infrastructure/adapters/productService/ProductServiceAdapter.java
@Component
public class ProductServiceAdapter implements ProductService {
private final ProductServiceFeignClient client;
// Implementation
}
// infrastructure/adapters/productService/ProductServiceFeignClient.java
@FeignClient(name = "product-service", url = "${urls.product-service}")
public interface ProductServiceFeignClient {
@GetMapping("/api/v1/products/{id}")
ProductDto getProduct(@PathVariable UUID id);
}
`
Configuration Added:
`yaml
parameters/local/urls.yaml
urls:
product-service: http://localhost:8041
`
Example:
`bash
eva4j g http-exchange order product-service
eva4j g http-exchange user payment-gateway
`
---
$3
Create Kafka event publisher with topic configuration.
`bash
eva4j generate kafka-event [event-name]
eva4j g kafka-event [event-name]
`
Prerequisites: Kafka client must be installed
Interactive Prompts:
- Event name (if not provided)
- Number of partitions (default: 3)
- Number of replicas (default: 1)
Generated Structure:
`java
// application/events/UserCreatedEvent.java
public record UserCreatedEvent(UUID id, String name, String email) {}
// application/ports/MessageBroker.java (created/updated)
public interface MessageBroker {
void publishUserCreatedEvent(UserCreatedEvent event);
}
// infrastructure/adapters/kafkaMessageBroker/KafkaMessageBroker.java
@Component
public class KafkaMessageBroker implements MessageBroker {
public void publishUserCreatedEvent(UserCreatedEvent event) {
kafkaTemplate.send("USER_CREATED", envelope);
}
}
`
Configuration Added:
`yaml
parameters/local/kafka.yaml
spring.kafka:
topics:
user-created: USER_CREATED
`
Usage in Code:
`java
@ApplicationComponent
public class CreateUserCommandHandler {
private final MessageBroker messageBroker;
public UserResponseDto handle(CreateUserCommand command) {
// ... create user
messageBroker.publishUserCreatedEvent(
new UserCreatedEvent(user.getId(), user.getName(), user.getEmail())
);
return dto;
}
}
`
Example:
`bash
eva4j g kafka-event user user-created
eva4j g kafka-event order order-placed
eva4j g kafka-event product stock-updated
`
---
$3
Create individual Kafka event listener classes for consuming events from topics.
`bash
eva4j generate kafka-listener
eva4j g kafka-listener
`
Prerequisites:
- Kafka client must be installed
- At least one topic must exist in kafka.yaml
Interactive Prompts:
- Select topics to listen to (checkbox, multiple selection)
Generated Structure:
`java
// infrastructure/kafkaListener/UserUserCreatedListener.java (one class per topic)
@Component("userUserCreatedListener")
public class UserUserCreatedListener {
private final UseCaseMediator useCaseMediator;
@Value("${topics.user-created}")
private String userCreatedTopic;
public UserUserCreatedListener(UseCaseMediator useCaseMediator) {
this.useCaseMediator = useCaseMediator;
}
@KafkaListener(topics = "${topics.user-created}")
public void handle(EventEnvelope`
Key Features:
- โ
Individual class per topic (Open/Closed Principle)
- โ
Module-prefixed names: UserUserCreatedListener, NotificationUserCreatedListener
- โ
Explicit bean names to avoid conflicts: @Component("userUserCreatedListener")
- โ
Manual acknowledgment control
- โ
UseCaseMediator integration
Example:
`bash
eva4j g kafka-listener notification
Select: user-created, order-placed
Generates: NotificationUserCreatedListener.java, NotificationOrderPlacedListener.java
`
---
$3
Extract a module from the monolith into an independent microservice.
`bash
eva4j detach [module-name]
`
Interactive Prompts:
- Module name (if not provided)
- Confirmation with summary
What it does:
1. Creates new project in sibling directory ({module-name}_msvc)
2. Copies entire module directory
3. Merges shared components into module/domain and module/infrastructure
4. Updates all package references (shared โ module-name)
5. Copies test files
6. Copies environment configurations (develop, test, production)
7. Copies parameters folder (kafka.yaml, urls.yaml)
8. Updates Kafka configuration references
9. Removes Spring Modulith dependencies
10. Increments server port (+1)
11. Uses parent's database configuration
Example:
`bash
In monolith project
eva4j detach user
Creates: ../user_msvc/
Port: parent port + 1
Database: same as parent
Structure: standalone microservice
`
Generated Microservice:
`
user_msvc/
โโโ build.gradle # NO Spring Modulith, includes Kafka if parent has it
โโโ .eva4j.json # Independent configuration
โโโ src/
โโโ main/java/.../user/
โ โโโ domain/
โ โ โโโ annotations/ # Merged from shared
โ โ โโโ customExceptions/ # Merged from shared
โ โ โโโ models/ # Original module entities
โ โโโ infrastructure/
โ โ โโโ configurations/ # Merged from shared
โ โ โโโ filters/ # Merged from shared
โ โ โโโ database/ # Original module repos
โ โ โโโ rest/ # Original module controllers
โ โโโ application/ # Original module use cases
โโโ resources/
โโโ application.yaml # Updated port
โโโ application-develop.yaml # Copied from parent
โโโ parameters/ # Copied and updated
โโโ */kafka.yaml # Package refs updated
`
Deploy Strategy:
`bash
Development: Run monolith
cd my-shop
./gradlew bootRun
Production: Deploy microservices
cd user_msvc && ./gradlew bootJar
cd order_msvc && ./gradlew bootJar
cd product_msvc && ./gradlew bootJar
`
---
$3
Display project configuration and module history.
`bash
eva4j info
`
Output Example:
`
๐ฆ Eva4j Project Information
Project Details:
Name: my-shop
Group ID: com.company
Artifact ID: my-shop
Package: com.company.myshop
Database: postgresql
Versions:
Java: 21
Spring Boot: 3.5.5
Spring Modulith: 1.4.6
Dependencies:
โข web
โข data-jpa
โข validation
โข actuator
Features:
โข kafka
Modules:
โข user (soft-delete, audit) - Created: 2026-01-27
โข product (soft-delete, audit) - Created: 2026-01-27
โข order (soft-delete, audit) - Created: 2026-01-28
Timestamps:
Created: 1/27/2026, 10:25:00 AM
Last Updated: 1/28/2026, 3:45:00 PM
`
---
๐๏ธ Development Workflow
$3
`bash
1. Create project
eva4j create e-commerce
cd e-commerce
2. Add modules
eva4j add module user
eva4j add module product
eva4j add module order
3. Generate resources
eva4j g resource user
eva4j g resource product
eva4j g resource order
4. Add event-driven communication
eva4j add kafka-client
eva4j g kafka-event order order-placed
eva4j g kafka-listener notification
5. Add external service clients
eva4j g http-exchange order payment-service
6. Run entire system locally
./gradlew bootRun
All modules run in single JVM on port 8040
`
Benefits during development:
- โ
Fast compilation and restart
- โ
Easy debugging with breakpoints across modules
- โ
Simple testing without container orchestration
- โ
Immediate refactoring across modules
- โ
Spring Modulith validates module boundaries
---
$3
`bash
Extract modules to microservices
eva4j detach user # Port 8041
eva4j detach product # Port 8042
eva4j detach order # Port 8043
Deploy independently
cd ../user_msvc
./gradlew bootJar
docker build -t user-service .
kubectl apply -f k8s/user-service.yaml
cd ../product_msvc
./gradlew bootJar
docker build -t product-service .
kubectl apply -f k8s/product-service.yaml
cd ../order_msvc
./gradlew bootJar
docker build -t order-service .
kubectl apply -f k8s/order-service.yaml
`
Benefits in production:
- โ
Independent scaling (scale order service 10x, user service 2x)
- โ
Isolated deployments (update order service without touching users)
- โ
Team autonomy (different teams own different services)
- โ
Technology flexibility (add Kotlin to new service if needed)
- โ
Fault isolation (product service down doesn't crash orders)
---
๐ Project Structure
`
my-project/
โโโ build.gradle # Dependencies with Spring Modulith
โโโ settings.gradle
โโโ .eva4j.json # Project configuration
โโโ docker-compose.yaml # Local database
โโโ README.md
โโโ src/
โโโ main/
โ โโโ java/com/company/myproject/
โ โ โโโ Application.java # Main class
โ โ โโโ shared/ # Cross-cutting concerns
โ โ โ โโโ domain/
โ โ โ โ โโโ annotations/ # @DomainComponent
โ โ โ โ โโโ customExceptions/ # Domain exceptions
โ โ โ โ โโโ errorMessage/ # Error messages
โ โ โ โ โโโ interfaces/ # Base entities
โ โ โ โโโ infrastructure/
โ โ โ โโโ configurations/ # Swagger, Jackson
โ โ โ โโโ eventEnvelope/ # Event wrapper
โ โ โ โโโ filters/ # Logging filters
โ โ โ โโโ handlerException/ # Global handler
โ โ โโโ user/ # User module
โ โ โ โโโ package-info.java # @ApplicationModule
โ โ โ โโโ application/ # Use cases layer
โ โ โ โ โโโ commands/
โ โ โ โ โโโ queries/
โ โ โ โ โโโ usecases/
โ โ โ โ โโโ dtos/
โ โ โ โ โโโ events/
โ โ โ โ โโโ mappers/
โ โ โ โ โโโ ports/
โ โ โ โโโ domain/ # Domain layer
โ โ โ โ โโโ models/
โ โ โ โ โ โโโ entities/
โ โ โ โ โ โโโ valueObjects/
โ โ โ โ โโโ repositories/
โ โ โ โ โโโ services/
โ โ โ โโโ infrastructure/ # Infrastructure layer
โ โ โ โโโ adapters/
โ โ โ โโโ database/
โ โ โ โโโ kafkaListener/
โ โ โ โโโ rest/
โ โ โ โโโ controllers/
โ โ โ โโโ validators/
โ โ โโโ product/ # Product module
โ โ โโโ ... (same structure)
โ โโโ resources/
โ โโโ application.yaml # Main config (port 8040)
โ โโโ application-local.yaml # Local profile
โ โโโ application-develop.yaml # Development profile
โ โโโ application-test.yaml # Test profile
โ โโโ application-production.yaml # Production profile
โ โโโ parameters/
โ โโโ local/
โ โ โโโ kafka.yaml # Kafka config (localhost)
โ โ โโโ urls.yaml # Service URLs (localhost)
โ โโโ develop/
โ โ โโโ kafka.yaml
โ โ โโโ urls.yaml
โ โโโ test/
โ โ โโโ kafka.yaml
โ โ โโโ urls.yaml
โ โโโ production/
โ โโโ kafka.yaml
โ โโโ urls.yaml
โโโ test/
โโโ java/com/company/myproject/
โโโ ApplicationTests.java
`
---
๐ Architecture Principles
$3
`
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Infrastructure โ
โ (REST, Kafka, Database, HTTP) โ
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ
โ Adapters
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโ
โ Application โ
โ (Use Cases, Ports, DTOs) โ
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ
โ Uses
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโ
โ Domain โ
โ (Entities, Value Objects, Logic) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
`
Domain Layer: Pure business logic, no frameworks
Application Layer: Use cases, coordinates domain and infrastructure
Infrastructure Layer: Framework integration (Spring, JPA, Kafka)
---
$3
Commands (write operations):
`java
record CreateUserCommand(String name, String email) {}
@ApplicationComponent
class CreateUserCommandHandler {
public UserResponseDto handle(CreateUserCommand command) {
// Validate, create entity, persist, publish event
}
}
`
Queries (read operations):
`java
record FindUserQuery(UUID id) {}
@ApplicationComponent
class FindUserQueryHandler {
public UserResponseDto handle(FindUserQuery query) {
// Fetch and return data
}
}
`
---
$3
`java
@ApplicationModule
package com.company.myproject.user;
// โ
Allowed: user โ shared
// โ
Allowed: user.infrastructure โ user.application โ user.domain
// โ Forbidden: user โ product (direct module dependency)
// โ Forbidden: user.domain โ user.infrastructure (wrong direction)
`
Validation:
`bash
./gradlew test
Spring Modulith validates architecture at test time
Generates documentation at target/spring-modulith-docs/
`
---
๐ Environment Management
Eva4j projects support 4 environments out of the box:
| Environment | Profile | Use Case | Config File |
|-------------|---------|----------|-------------|
| local | local | Developer machine | application-local.yaml |
| develop | develop | Development server | application-develop.yaml |
| test | test | QA/Staging | application-test.yaml |
| production | production | Production | application-production.yaml |
Run with profile:
`bash
Local (default)
./gradlew bootRun
Development server
./gradlew bootRun --args='--spring.profiles.active=develop'
Production
java -jar app.jar --spring.profiles.active=production
`
Environment-specific Kafka & URLs:
`
resources/parameters/
โโโ local/
โ โโโ kafka.yaml # bootstrap-servers: localhost:9092
โ โโโ urls.yaml # product-service: http://localhost:8041
โโโ develop/
โ โโโ kafka.yaml # bootstrap-servers: dev-kafka.company.com:9092
โ โโโ urls.yaml # product-service: https://dev-product.company.com
โโโ production/
โโโ kafka.yaml # bootstrap-servers: prod-kafka.company.com:9092
โโโ urls.yaml # product-service: https://product.company.com
`
---
๐งช Testing
`bash
Run all tests
./gradlew test
Run specific module tests
./gradlew :test --tests com.company.myproject.user.*
Spring Modulith generates architecture docs
Check: target/spring-modulith-docs/
``