728x90
실제 HTTP 요청 → 서버 내부 레이어 → DB → 응답 반환까지,
스프링부트에서 DAO(Repository), Entity, DTO, Service가 어떻게 흘러가는지 실제 코드 흐름은 아래와 같다
✔ 전체 구조 (먼저 큰 흐름)
[클라이언트]
↓ HTTP 요청
[Controller]
↓
[Service]
↓
[DAO / Repository]
↓
[Entity]
↓
[DB]
그리고 응답은 반대로 올라옵니다.
✔ 상황
👉 회원 조회 API
GET /users/1
1️⃣ 클라이언트 → HTTP 요청
예시 (curl)
curl http://localhost:8080/users/1
2️⃣ Controller (HTTP 입구)
👉 HTTP 요청 받는 역할
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public UserResponse getUser(@PathVariable Long id) {
return userService.getUser(id);
}
}
✔ 역할
- URL 매핑
- HTTP 요청 파싱
- Service 호출
- Response 반환
3️⃣ Service (비즈니스 로직 담당)
👉 실제 서비스 로직 처리
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public UserResponse getUser(Long id) {
User user = userRepository.findById(id)
.orElseThrow();
return new UserResponse(user.getName(), user.getEmail());
}
}
✔ 역할
- 비즈니스 로직
- 트랜잭션 관리
- Entity → DTO 변환
4️⃣ DAO / Repository (DB 접근 담당)
👉 DAO 역할
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
✔ 내부에서 하는 일
Spring Data JPA가 자동으로 아래 SQL 실행
SELECT * FROM users WHERE id = 1
5️⃣ Entity (DB 테이블 매핑)
@Entity
@Table(name = "users")
public class User {
@Id
private Long id;
private String name;
private String email;
protected User() {}
public String getName() { return name; }
public String getEmail() { return email; }
}
👉 DB 테이블과 1:1 연결
6️⃣ DTO (응답용 객체)
👉 클라이언트에게 전달되는 데이터
public class UserResponse {
private String name;
private String email;
public UserResponse(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() { return name; }
public String getEmail() { return email; }
}
✔ 실제 전체 실행 흐름 (타임라인)
① HTTP 요청 발생
GET /users/1
② Controller 실행
UserController.getUser(1)
③ Service 호출
userService.getUser(1)
④ Repository 호출
userRepository.findById(1)
⑤ JPA가 SQL 실행
SELECT * FROM users WHERE id = 1
⑥ DB → Entity 생성
User 객체 생성
⑦ Service에서 DTO 변환
User → UserResponse
⑧ Controller → JSON 응답
{ "name": "홍길동", "email": "hong@test.com" }
✔ 시각 흐름도
[Browser / curl]
│
▼
Controller (HTTP 처리)
│
▼
Service (비즈니스 로직)
│
▼
Repository / DAO (DB 접근)
│
▼
Entity (테이블 매핑)
│
▼
DB
✔ 각 레이어 존재 이유
Controller
👉 HTTP 전용 처리
Service
👉 로직 중심
DAO / Repository
👉 DB 접근 분리
Entity
👉 DB 구조 표현
DTO
👉 외부 공개 데이터
✔ 왜 이렇게 나누냐 (핵심 이유)
유지보수
레이어별 수정 가능
테스트
Service만 단위 테스트 가능
보안
Entity 그대로 노출 방지
확장성
DB 교체 쉬움
✔ 정리 > HTTP 하나가 지나갈 때
보통 이런 객체들이 생성됩니다.
Request DTO
↓
Controller
↓
Service
↓
Entity
↓
Repository
↓
DB
↓
Entity
↓
Response DTO
✔ 간단 정리
스프링부트에서 HTTP 요청은 Controller에서 시작되어 Service에서 비즈니스 로직을 처리하고, Repository(DAO)를 통해 DB에 접근하며, Entity로 DB 데이터를 매핑한 뒤 DTO로 변환되어 클라이언트에게 응답된다. 이러한 계층 분리는 보안, 유지보수성, 테스트 용이성, 확장성을 확보하기 위해 사용된다.
✔ 한줄 소감
레이어 분리는 단순한 구조 나누기가 아니라 안정성과 유연성을 위한 설계 철학이라는 점을 이해하게 되었다.
728x90
'백엔드 > 스프링' 카테고리의 다른 글
| 스프링 부트 - CI / CD - (1) (0) | 2026.03.08 |
|---|---|
| 스피링 부트 - 배포 using AWS RDS (0) | 2026.03.03 |
| 스프링 부트 - OAuth2 로그인 구현 과정 흐름 설명 (0) | 2026.03.01 |
| 스프링 어노테이션 정리 (@Data, @NoArgsConstructor, @AllArgsConstuctor) (1) | 2023.10.21 |
| 스프링 용어 및 짤개념 정리 - 1 (0) | 2023.10.15 |
