Skip to content

04 - เข้าใจโครงสร้างโปรเจกต์

บทนี้อธิบายโครงสร้าง project ที่จะใช้ทั้งเล่ม เพื่อให้รู้ว่า code แต่ละประเภทควรอยู่ที่ไหน

ทำไมต้องจัดโครงสร้าง

Section titled “ทำไมต้องจัดโครงสร้าง”

ตอน project เล็ก จะเขียนทุกอย่างไว้ใน controller ก็ยังพอรันได้ แต่เมื่อมี register, login, JWT, role, admin endpoint, validation, exception และ database โค้ดจะเริ่มอ่านยากทันที

การแยก layer ทำให้:

  • code อ่านง่าย
  • feature ใหม่เพิ่มง่าย
  • test ง่ายขึ้น
  • เปลี่ยน implementation ภายในได้โดยไม่กระทบ API มากเกินไป

ในหนังสือจะใช้ package:

com.example.backendapi
config
controller
dto
exception
model
repository
service

หน้าที่แต่ละ package

Section titled “หน้าที่แต่ละ package”

รับ HTTP request และส่ง response

ตัวอย่าง:

AuthController
UserController
AdminUserController

Controller ไม่ควรคุยกับ database โดยตรง

เก็บ business logic ของระบบ

ตัวอย่าง:

AuthService
UserService
AdminUserService
JwtService

Service เป็นที่ที่เราตรวจ email ซ้ำ, hash password, สร้าง JWT และเปลี่ยน role

ติดต่อ database ผ่าน Spring Data JPA

ตัวอย่าง:

public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}

เก็บ Entity ที่ map กับ database table

ตัวอย่าง:

User
AuditLog
Role
UserStatus

เก็บ object ที่ใช้รับ request และส่ง response

ตัวอย่าง:

RegisterRequest
LoginRequest
LoginResponse
UserResponse

DTO ช่วยให้เราไม่ต้องส่ง Entity ตรง ๆ ออก API

เก็บ custom exception และ global exception handler

ตัวอย่าง:

UserNotFoundException
EmailAlreadyUsedException
GlobalExceptionHandler

เก็บ configuration ที่ต้องใช้ทั้งระบบ

ตัวอย่าง:

SecurityConfig
OpenApiConfig
JwtConfig
POST /api/v1/auth/register
|
v
AuthController
|
v
AuthService
|
v
UserRepository
|
v
PostgreSQL

ลำดับจริง:

  1. AuthController รับ RegisterRequest
  2. AuthService ตรวจ username/email ซ้ำ
  3. AuthService hash password
  4. UserRepository save user
  5. AuthService แปลง User เป็น UserResponse
  6. Controller ส่ง response กลับ

สร้าง package เหล่านี้ใต้ com.example.backendapi

config
controller
dto
exception
model
repository
service

ช่วงแรกบาง package ยังว่างได้ ไม่เป็นไร เราจะค่อย ๆ เติมเมื่อถึงบทที่เกี่ยวข้อง

ถ้าไม่แน่ใจว่า code ควรอยู่ไหน ให้ถามแบบนี้:

  • รับ HTTP request หรือไม่: controller
  • เป็น business rule หรือไม่: service
  • ติดต่อ database หรือไม่: repository
  • แทน table หรือไม่: model
  • เป็น request/response หรือไม่: dto
  • เป็น config ทั้งระบบหรือไม่: config

แบบฝึกหัดท้ายบท

Section titled “แบบฝึกหัดท้ายบท”

สร้าง package ตามบทนี้ แล้ว commit เป็น checkpoint แรก:

Terminal window
git add .
git commit -m "Create base package structure"