git clone https://github.com/Jye-a-dev/template_spingBoot_serverTemplate khởi tạo cho backend REST API theo hướng module rõ ràng, dùng:
- Java 21
- Spring Boot 4
- Spring Web MVC
- Spring Data JPA
- Jakarta Validation
- Maven
- H2 database cho dev/test nhanh
- PostgreSQL driver cho production hoặc database thật
- Cấu trúc module theo controller/service/repository/entity/dto/mapper
- Placeholder cho config, constants, enums, exceptions, security và utils
- File
.mdsong ngữ trong từng folder chính để giải thích vai trò thư mục
Template này phù hợp khi bạn muốn bắt đầu nhanh với một REST API server Java rõ cấu trúc, dễ copy module, dễ test và dễ mở rộng khi dự án lớn hơn.
Repo hiện tại là kiểu:
Java 21 + Spring Boot + Spring Web MVC + Spring Data JPA + Maven
Đây là setup phù hợp cho:
- REST API backend
- Backend cho React/Vue/Next client riêng
- Admin API
- Service nhỏ hoặc vừa
- Dự án cần cấu trúc module rõ ràng
- Dự án cần validation request bằng annotation
- Dự án cần database qua JPA/Hibernate
- Team muốn dùng hệ sinh thái Spring Boot
- Dự án có khả năng mở rộng thêm PostgreSQL, auth, security, exception handler và Swagger/OpenAPI
Hiện tại repo có module users làm ví dụ thật. Module này đã có controller, service, repository, entity, DTO, mapper và test bằng MockMvc.
Đây là kiểu setup của repo này.
Dùng khi:
- muốn xây REST API truyền thống
- muốn cấu trúc rõ và dễ học
- cần controller/service/repository quen thuộc
- cần tích hợp database bằng JPA
- cần framework phổ biến, nhiều tài liệu
- muốn chạy tốt cho dự án nhỏ, vừa và có thể mở rộng lớn hơn
Dùng khi:
- cần reactive programming
- cần xử lý nhiều request I/O đồng thời
- team đã quen với Reactor, Mono và Flux
- dự án có nhu cầu non-blocking rõ ràng
Nếu mới học backend hoặc đang làm REST API thông thường, Spring Web MVC dễ bắt đầu hơn WebFlux.
Dùng khi:
- database là phần chính của app
- muốn thao tác entity/repository rõ ràng
- muốn Hibernate tự mapping object sang table
- cần transaction, query method và repository pattern
Dùng khi:
- muốn tự kiểm soát SQL nhiều hơn
- không muốn dùng ORM
- query phức tạp và cần tối ưu sát database
- team quen viết SQL trực tiếp
Nên dùng Node.js backend khi:
- team quen TypeScript hơn Java
- cần server nhẹ, khởi động nhanh
- dự án nhỏ hoặc realtime nhiều
- muốn ecosystem npm
Nên dùng Spring Boot khi:
- cần backend Java ổn định
- cần transaction/database mạnh
- cần kiến trúc enterprise hơn
- team quen Java hoặc muốn học Java backend bài bản
- Java 21
- Maven Wrapper đã có sẵn trong repo
- Eclipse hoặc IDE Java bất kỳ
Kiểm tra Java:
java -versionMaven sẽ tự tải dependency khi build hoặc test:
./mvnw testTrên Windows:
.\mvnw.cmd testTrên Windows:
.\mvnw.cmd spring-boot:runTrên macOS/Linux:
./mvnw spring-boot:runHoặc chạy trong Eclipse:
src/main/java/com/example/server/ServerApplication.java
Chuột phải vào file đó:
Run As -> Java Application
Nếu có Spring Tools:
Run As -> Spring Boot App
./mvnw clean packageTrên Windows:
.\mvnw.cmd clean packagejava -jar target/springboot-0.0.1-SNAPSHOT.jar./mvnw testTrên Windows:
.\mvnw.cmd testRepo hiện đã có test thật:
- context load test cho Spring Boot app
- MockMvc test cho API users
Sau khi chạy server, app mặc định chạy tại:
http://localhost:8080
Các API hiện có:
POST http://localhost:8080/api/users
GET http://localhost:8080/api/users
GET http://localhost:8080/api/users/{id}
Ví dụ tạo user:
{
"name": "Test User",
"email": "test@example.com"
}src/
├─ src.md
├─ main/
│ ├─ main.md
│ ├─ java/
│ │ ├─ java.md
│ │ └─ com/
│ │ ├─ com.md
│ │ └─ example/
│ │ ├─ example.md
│ │ └─ server/
│ │ ├─ server.md
│ │ ├─ ServerApplication.java
│ │ ├─ config/
│ │ │ └─ config.md
│ │ ├─ constants/
│ │ │ └─ constants.md
│ │ ├─ enums/
│ │ │ └─ enums.md
│ │ ├─ exceptions/
│ │ │ └─ exceptions.md
│ │ ├─ modules/
│ │ │ ├─ modules.md
│ │ │ └─ users/
│ │ │ ├─ users.md
│ │ │ ├─ UserController.java
│ │ │ ├─ UserService.java
│ │ │ ├─ UserRepository.java
│ │ │ ├─ UserEntity.java
│ │ │ ├─ dto/
│ │ │ │ ├─ dto.md
│ │ │ │ ├─ CreateUserRequest.java
│ │ │ │ └─ UserResponse.java
│ │ │ └─ mapper/
│ │ │ ├─ mapper.md
│ │ │ └─ UserMapper.java
│ │ ├─ security/
│ │ │ └─ security.md
│ │ └─ utils/
│ │ └─ utils.md
│ └─ resources/
│ ├─ resources.md
│ ├─ application.yml
│ ├─ static/
│ │ └─ static.md
│ └─ templates/
│ └─ templates.md
└─ test/
├─ test.md
├─ java/
│ ├─ java.md
│ └─ com/
│ ├─ com.md
│ └─ example/
│ ├─ example.md
│ └─ server/
│ ├─ server.md
│ ├─ ServerApplicationTests.java
│ └─ modules/
│ ├─ modules.md
│ └─ users/
│ ├─ users.md
│ └─ UserControllerTest.java
└─ resources/
├─ resources.md
├─ application.yml
└─ application-test.yml
Ý nghĩa chính:
config/: cấu hình app, bean, CORS, Swagger hoặc framework setupconstants/: hằng số dùng chungenums/: enum dùng trong appexceptions/: custom exception và error handlingmodules/: nơi đặt các module nghiệp vụmodules/users/: module user mẫudto/: request và response objectmapper/: chuyển đổi entity sang response hoặc request sang entitysecurity/: cấu hình authentication/authorization sau nàyutils/: helper dùng chungresources/: cấu hình app, static files và templatestest/: test code và test resourcesServerApplication.java: entry khởi động Spring Boot
Luồng cơ bản:
ServerApplication.javakhởi động Spring Boot.- Spring Boot scan package
com.example.server. - Spring tạo bean cho controller, service, repository và mapper.
- Request đi vào
UserController. - Controller nhận request và gọi
UserService. - Service xử lý business logic.
- Service gọi
UserRepositoryđể thao tác database. - Repository dùng JPA/Hibernate để làm việc với table
users. - Mapper đổi entity thành response DTO.
- Controller trả JSON response cho client.
Tóm tắt:
ServerApplication.java
-> UserController
-> UserService
-> UserRepository
-> UserEntity
-> UserMapper
-> UserResponse
Mỗi module nên có cấu trúc:
src/main/java/com/example/server/modules/products/
├─ products.md
├─ ProductController.java
├─ ProductService.java
├─ ProductRepository.java
├─ ProductEntity.java
├─ dto/
│ ├─ dto.md
│ ├─ CreateProductRequest.java
│ ├─ UpdateProductRequest.java
│ └─ ProductResponse.java
└─ mapper/
├─ mapper.md
└─ ProductMapper.java
Ý nghĩa từng phần:
Controller: nhận HTTP request, gọi service, trả responseService: xử lý business logic chính của moduleRepository: truy xuất databaseEntity: mapping với table trong databaseDTO: định nghĩa dữ liệu request/responseMapper: chuyển đổi giữa entity và DTO*.md: tài liệu mô tả folder/module bằng English và tiếng Việt
Có thể copy folder:
src/main/java/com/example/server/modules/users
Sau đó đổi tên class và endpoint theo module thật.
Ví dụ:
UserController.java
-> ProductController.java
Repo hiện tại đang dùng package dạng lowercase:
com.example.server.modules.users
Nếu tên module có nhiều từ, nên dùng lowercase liền hoặc rõ nghĩa:
userprofiles
orderitems
Trong Java, package thường không dùng dấu gạch ngang và không dùng chữ hoa.
Dùng PascalCase theo feature:
UserController.java
UserService.java
UserRepository.java
UserEntity.java
UserMapper.java
Ví dụ module products:
ProductController.java
ProductService.java
ProductRepository.java
ProductEntity.java
ProductMapper.java
Dùng format:
CreateModuleRequest.java
UpdateModuleRequest.java
ModuleResponse.java
Ví dụ:
CreateProductRequest.java
UpdateProductRequest.java
ProductResponse.java
Endpoint nên dùng plural noun:
/api/users
/api/products
/api/orders
Repo đã dùng:
spring-boot-starter-validation
DTO request có thể dùng annotation:
@NotBlank
private String name;
@Email
@NotBlank
private String email;Controller bật validation bằng:
public UserResponse create(@Valid @RequestBody CreateUserRequest request)Mục tiêu:
- không validate thủ công trong controller
- giữ request rule trong DTO
- giảm lỗi dữ liệu vào service
- dễ đọc và dễ test
Repo hiện dùng H2 cho dev/test nhanh:
spring:
datasource:
url: jdbc:h2:mem:server_devTest dùng H2 memory database:
src/test/resources/application.yml
Repo cũng đã có PostgreSQL driver:
<artifactId>postgresql</artifactId>Khi muốn dùng PostgreSQL thật, có thể đổi application.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/server_db
username: postgres
password: your_password
jpa:
hibernate:
ddl-auto: updateTrong production, nên cân nhắc dùng migration tool như Flyway hoặc Liquibase thay vì chỉ dựa vào ddl-auto.
Hiện repo mới throw IllegalArgumentException trong service khi:
- email đã tồn tại
- user không tồn tại
Khi phát triển tiếp, nên thêm global exception handler trong:
src/main/java/com/example/server/exceptions/
Mục tiêu:
- response lỗi thống nhất
- map lỗi nghiệp vụ sang HTTP status phù hợp
- không để controller xử lý lỗi lặp lại
- không leak stack trace ở production
Gợi ý class sau này:
GlobalExceptionHandler.java
ApiErrorResponse.java
NotFoundException.java
ConflictException.java
Folder security hiện là placeholder:
src/main/java/com/example/server/security/
Khi cần auth, có thể thêm:
- Spring Security
- JWT authentication
- role/permission
- password encoder
- security filter chain
Ví dụ dependency sau này:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>Không nên thêm security quá sớm nếu app đang ở giai đoạn học cấu trúc controller/service/repository.
Repo hiện chưa cài Swagger.
Khi cần API docs, có thể dùng springdoc-openapi.
Ví dụ dependency:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>latest-compatible-version</version>
</dependency>Sau khi cấu hình xong, Swagger UI thường ở:
http://localhost:8080/swagger-ui/index.html
Nên kiểm tra version tương thích với Spring Boot 4 trước khi cài.
Folder config hiện là placeholder:
src/main/java/com/example/server/config/
Có thể dùng để đặt:
- CORS config
- Jackson config
- Web MVC config
- Swagger config
- Bean dùng chung
Ví dụ sau này:
CorsConfig.java
WebConfig.java
OpenApiConfig.java
- Controller chỉ nhận request, gọi service và trả response
- Service chứa business logic
- Repository chỉ lo truy xuất database
- Entity đại diện cho table/database model
- DTO đại diện dữ liệu đi vào và đi ra API
- Mapper chuyển đổi giữa entity và DTO
- Config nên nằm trong
config - Exception handling nên nằm trong
exceptions - Security nên nằm trong
security - Utils nên là helper tổng quát, không phụ thuộc module cụ thể
- Không nhồi business logic vào
ServerApplication.java - Không để controller gọi trực tiếp quá nhiều query phức tạp
- Không để entity lộ trực tiếp ra API response nếu app bắt đầu lớn
Khi app tăng độ phức tạp, có thể mở rộng thêm:
auth/roles/permissions/products/orders/files/emails/jobs/cache/database/logging/notifications/
Ví dụ:
src/main/java/com/example/server/
├─ config/
├─ constants/
├─ exceptions/
├─ modules/
│ ├─ auth/
│ ├─ users/
│ ├─ products/
│ └─ orders/
├─ security/
└─ utils/
Nếu team đi theo feature-based architecture, có thể giữ controller, service, repository, entity, DTO và mapper trong từng module như template hiện tại.
Repository nên giữ riêng khi:
- service bắt đầu có nhiều query database
- nhiều service cùng cần truy xuất một entity
- muốn test business logic dễ hơn
- muốn controller/service không phụ thuộc chi tiết database
- muốn đổi query hoặc database ít ảnh hưởng tầng API
Mapper nên giữ riêng khi:
- response không giống entity
- cần ẩn field nhạy cảm
- cần format dữ liệu trước khi trả cho client
- nhiều endpoint dùng cùng cách chuyển đổi
Không cần tạo quá nhiều abstraction nếu module vẫn rất nhỏ, nhưng với Spring Boot thì controller/service/repository là cấu trúc rất quen thuộc và dễ mở rộng.
Import project:
File->ImportMaven->Existing Maven Projects- Chọn folder project
- Tick
pom.xml - Bấm
Finish
Update Maven nếu Eclipse chưa nhận dependency:
Right click project -> Maven -> Update Project...
Chạy app:
src/main/java/com/example/server/ServerApplication.java
Chuột phải:
Run As -> Java Application
Chạy test:
Right click project -> Run As -> Maven test
Hoặc chạy từng test:
Right click UserControllerTest.java -> Run As -> JUnit Test
Dừng server trong Eclipse:
Console tab -> bấm nút ô vuông đỏ Terminate
- clone repo
- import vào Eclipse hoặc IDE
- kiểm tra Java 21
- chạy
mvnw test - đổi package/project name nếu cần
- kiểm tra
application.yml - tạo module mới từ module
users - viết DTO trước khi viết controller
- giữ business logic trong service
- tách mapper khi response khác entity
- thêm global exception handler khi có nhiều lỗi nghiệp vụ
- chuyển sang PostgreSQL khi cần database thật
- thêm Swagger khi API bắt đầu nhiều endpoint
- chạy
mvnw clean testtrước khi commit
Nếu muốn biến template này thành base mạnh hơn, có thể thêm:
- global exception handler hoàn chỉnh
- response format thống nhất
- Spring Security
- JWT auth flow
- role/permission
- PostgreSQL config thật
- Flyway hoặc Liquibase migration
- Swagger/OpenAPI
- Dockerfile
- Docker Compose cho database
- request logging
- pagination helper
- base entity có
createdAt,updatedAt - CI check build/test
- testcontainers cho integration test
Nếu bạn muốn một setup backend cân bằng giữa:
- dễ bắt đầu
- dễ đọc
- cấu trúc rõ
- quen thuộc với Java backend
- dễ test
- dễ mở rộng database/auth/swagger sau này
- phù hợp học Spring Boot bài bản
thì Java + Spring Boot + Maven + JPA là lựa chọn rất thực dụng.
Template này đang đi theo hướng đó:
- entry rõ
- module users mẫu rõ
- controller/service/repository/entity tách riêng
- DTO và mapper riêng
- H2 chạy nhanh cho dev/test
- folder có tài liệu song ngữ
- dễ copy module để phát triển tiếp