Mộc Viên's Blog Mộc Viên's Blog
Cấu trúc thư mục chuẩn của một dự án Spring Boot

Cấu trúc thư mục chuẩn của một dự án Spring Boot

Ngày đăng:

Cấu trúc thư mục chuẩn của một dự án Spring Boot

Cấu trúc một dự án Spring Boot thường được tổ chức theo mô hình Layered Architecture, giúp code dễ quản lý, bảo trì và mở rộng.


📂 Cấu trúc thư mục chuẩn của một dự án Spring Boot

spring-boot-app/
│── src/
│   ├── main/
│   │   ├── java/com/example/app/
│   │   │   ├── controller/      # Xử lý request từ API
│   │   │   ├── service/         # Xử lý logic ứng dụng
│   │   │   ├── repository/      # Giao tiếp với database
│   │   │   ├── entity/          # Định nghĩa bảng database
│   │   │   ├── config/          # Cấu hình (CORS, Security, DB...)
│   │   │   ├── dto/             # Định nghĩa object chuyển đổi dữ liệu
│   │   │   ├── exception/       # Xử lý lỗi
│   │   │   ├── AppApplication.kt # File main khởi chạy app
│   │   ├── resources/
│   │   │   ├── application.properties (hoặc application.yml) # Cấu hình ứng dụng
│   │   │   ├── static/          # Chứa file tĩnh (CSS, JS, ảnh...)
│   │   │   ├── templates/       # Chứa template (Thymeleaf, Freemarker...)
│   ├── test/                    # Viết test cho ứng dụng
│── build.gradle.kts             # File build Gradle Kotlin
│── settings.gradle.kts          # Cấu hình Gradle
│── README.md                    # Hướng dẫn dự án
│── .gitignore                    # Ignore file không cần push lên Git

📌 Các thành phần chính của một dự án Spring Boot

1️⃣ Entity (Model) - Định nghĩa bảng database

📂 src/main/java/com/example/app/entity/User.kt

package com.example.app.entity

import jakarta.persistence.*

@Entity
@Table(name = "users")
data class User(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0,
    val name: String,
    val email: String
)

2️⃣ Repository - Tầng giao tiếp với Database

📂 src/main/java/com/example/app/repository/UserRepository.kt

package com.example.app.repository

import com.example.app.entity.User
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface UserRepository : JpaRepository<User, Long>

3️⃣ Service - Xử lý logic nghiệp vụ

📂 src/main/java/com/example/app/service/UserService.kt

package com.example.app.service

import com.example.app.entity.User
import com.example.app.repository.UserRepository
import org.springframework.stereotype.Service

@Service
class UserService(private val userRepository: UserRepository) {

    fun getAllUsers(): List<User> = userRepository.findAll()

    fun createUser(user: User): User = userRepository.save(user)
}

4️⃣ Controller - Xử lý API request

📂 src/main/java/com/example/app/controller/UserController.kt

package com.example.app.controller

import com.example.app.entity.User
import com.example.app.service.UserService
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/api/users")
class UserController(private val userService: UserService) {

    @GetMapping
    fun getAllUsers(): List<User> = userService.getAllUsers()

    @PostMapping
    fun createUser(@RequestBody user: User): User = userService.createUser(user)
}

5️⃣ Config - Cấu hình ứng dụng

📂 src/main/java/com/example/app/config/WebConfig.kt

package com.example.app.config

import org.springframework.context.annotation.Configuration
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer

@Configuration
class WebConfig : WebMvcConfigurer {
    override fun addCorsMappings(registry: CorsRegistry) {
        registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE")
    }
}

6️⃣ Exception - Xử lý lỗi

📂 src/main/java/com/example/app/exception/GlobalExceptionHandler.kt

package com.example.app.exception

import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler

@ControllerAdvice
class GlobalExceptionHandler {

    @ExceptionHandler(Exception::class)
    fun handleException(ex: Exception): ResponseEntity<String> {
        return ResponseEntity(ex.message, HttpStatus.INTERNAL_SERVER_ERROR)
    }
}

7️⃣ application.properties (hoặc application.yml) - Cấu hình database

📂 src/main/resources/application.properties

spring.application.name=SpringDemo
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

8️⃣ build.gradle.kts - Cấu hình Gradle

📂 build.gradle.kts

plugins {
    id("org.springframework.boot") version "3.2.2"
    id("io.spring.dependency-management") version "1.1.4"
    kotlin("jvm") version "1.9.21"
    kotlin("plugin.spring") version "1.9.21"
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-validation")
    implementation("org.postgresql:postgresql:42.6.0")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions.jvmTarget = "17"
}

🎯 Tóm tắt

📌 Thành phần 📝 Chức năng
entity/ Định nghĩa model (bảng database).
repository/ Truy vấn dữ liệu từ database (Sử dụng JPA/Hibernate).
service/ Xử lý logic nghiệp vụ, tách biệt với Controller.
controller/ Xử lý API request, gọi Service.
config/ Chứa các file cấu hình (CORS, Security, Logging...).
exception/ Xử lý lỗi toàn cục.
dto/ Chứa các object trung gian để chuyển đổi dữ liệu.
application.properties Cấu hình kết nối database và ứng dụng.
build.gradle.kts Cấu hình project với Gradle Kotlin DSL.

🚀 Chạy ứng dụng

1️⃣ Khởi động PostgreSQL
Nếu bạn đang chạy PostgreSQL trên Docker:

docker run --name postgres -e POSTGRES_USER=your_username -e POSTGRES_PASSWORD=your_password -e POSTGRES_DB=mydatabase -p 5432:5432 -d postgres

2️⃣ Chạy ứng dụng

./gradlew bootRun

3️⃣ Test API

Tạo User mới

curl -X POST http://localhost:8080/api/users -H "Content-Type: application/json" -d '{"name": "John Doe", "email": "[email protected]"}'

Lấy danh sách User

curl -X GET http://localhost:8080/api/users

💡 Vậy là bạn đã có một API Spring Boot kết nối PostgreSQL chạy bằng Gradle Kotlin. 🚀🔥

Quản lý các phiên bản khác nhau của API trong Spring Boot như thế nào?
Quản lý phiên bản API trong Spring Boot có thể thực hiện bằng nhiều cách khác nhau, tùy vào yêu cầu của hệ thống. Dưới đây là một số phương pháp phổ biến: 1. Sử dụng Đường dẫn (URI Versioning) Phương pháp này đặt phiên bản API trong URL, ví

Gần đây