A Spring Boot based multi-module template project.
This template provides a practical basic structure that follows domain-driven design principles.
root/
├── api/ # API module (web layer, executable module)
├── core/
│ ├── base/ # Common utilities (Pair, etc.)
│ └── domain/ # Domain logic + JPA entity integration
└── storage/
└── rdb/ # Database configuration and driver management
api -----> domain (JPA integrated) <----- base
|
└-----> storage/rdb (datasource)
- Domain is the center of the project
- Domain manages JPA entities and repositories together (practical approach)
- Storage handles pure datasource configuration and driver management
- Application entry point (
Application.java) - REST API controllers (
ApiController.java) - Executable application (port: 8081)
- JPA entities (
Version.java- using @EmbeddedId composite key) - Repository interfaces (
VersionRepository extends JpaRepository) - Business services (
VersionService.java) - Integrated management of all JPA-related logic
- Common utilities (
Pair<F,S>record class) - Basic functionality needed by domain
- Database-specific configuration and drivers
- Connection pool management
- Profile-based datasource separation
- Java: 21
- Spring Boot: 3.4.0
- Gradle: 8.11.1
- JPA: Hibernate 6.6.2 + Spring Data JPA
- Database: H2 (development), MySQL/PostgreSQL (production)
# Default execution - H2 in-memory DB
./gradlew :api:bootRun
# H2 Web Console access
http://localhost:8081/h2-console
JDBC URL: jdbc:h2:mem:testdb
User:
sa / Password: (empty)# Environment variables
export DB_USERNAME=your_username
export DB_PASSWORD=your_password
# Run with MySQL profile
./gradlew :api:bootRun --args='--spring.profiles.active=mysql'# Run with PostgreSQL profile
./gradlew :api:bootRun --args='--spring.profiles.active=postgresql'application-rdb.yml: H2 configuration (development)application-mysql.yml: MySQL configuration (production)application-postgresql.yml: PostgreSQL configuration (production)- Profile-based automatic switching
dependencies {
implementation(project(":storage:rdb")) # Datasource configuration
implementation project(':core:domain') # Domain + JPA
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
}dependencies {
api project(':core:base') # Expose base utilities
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}dependencies {
implementation 'com.h2database:h2' # H2 (development)
// runtimeOnly 'com.mysql:mysql-connector-j' # MySQL
// runtimeOnly 'org.postgresql:postgresql' # PostgreSQL
}GET /api
Response: Version object (major, minor, patch)@Entity
public class Version {
@EmbeddedId
private VersionId id; // Composite key: major, minor, patch
public static Version versionStart() {
return new Version(new VersionId(0, 0, 1));
}
}- Define only repository interfaces
- Automatic JPA implementation generation
- Automated transaction management
- Development: H2 in-memory + web console
- Production: MySQL/PostgreSQL + production settings
- Environment variable-based security
- Separation of compile-time and runtime dependencies
- Easy addition of new databases
- Separation of domain logic and infrastructure
- Add driver dependency to
storage/rdb/build.gradle - Create
application-{db}.ymlconfiguration file - Add
{Database}Configuration.javaif needed
- Create
core/domain/src/main/java/app/{domain}/package - Write Entity, Repository, Service classes
- Automatically included in
@EntityScanscope
# 1. Clone project
git clone [repository-url]
# 2. Build and run
./gradlew :api:bootRun
# 3. Test API
curl http://localhost:8081/api
# 4. Access H2 console
open http://localhost:8081/h2-consoleThis template provides a structure that follows the core principles of domain-driven design while enabling practical implementation.