
1. Controller
개념
- 애플리케이션의 입구 역할을 함.
- 사용자의 요청(Request)을 받아서, 이를 처리할 적절한 로직(Service)으로 전달.
- HTTP 요청과 응답을 관리.
용도
- URL 라우팅과 요청 처리.
- 요청 파라미터 검증(Validation).
- 적절한 Service를 호출하여 비즈니스 로직 수행.
- Service에서 처리된 결과를 클라이언트에게 반환(Response).
예시 (Node.js/Express):
// controller/userController.js
const userService = require('../service/userService');
exports.getUser = async (req, res) => {
const userId = req.params.id;
const user = await userService.findUserById(userId);
res.status(200).json(user);
};
2. Service
개념
- 비즈니스 로직을 처리하는 계층.
- 데이터베이스 작업이나 외부 API 호출 등 실제 처리해야 할 작업을 수행.
- Controller는 Service에 로직 처리를 위임하고, Service는 구체적인 일을 함.
용도
- 비즈니스 규칙 구현.
- 데이터베이스 쿼리 호출.
- 외부 API와의 통신.
- 여러 도메인 로직을 조합하여 작업 처리.
예시 (Node.js):
// service/userService.js
const User = require('../models/user');
exports.findUserById = async (userId) => {
return await User.findById(userId); // DB에서 사용자 정보 조회
};
3. Controller와 Service의 차이
구분 | Controller | Service |
주요 역할 | 요청 처리, 라우팅 | 비즈니스 로직 처리 |
관심사 | 요청과 응답, API 인터페이스 | 데이터 처리 및 도메인 로직 |
연결 대상 | 클라이언트 ↔ Service | Controller ↔ 데이터베이스/외부 시스템 |
위치 | 애플리케이션의 프레젠테이션 계층 | 애플리케이션의 도메인 계층 |
4. 왜 분리해야 할까?
관심사의 분리(SOC)
Controller는 클라이언트와의 상호작용에 집중. Service는 비즈니스 로직 구현에 집중.
재사용성 증가
Service는 다양한 Controller에서 재사용 가능.
유지보수성 향상
로직이 명확히 분리되어 있어서 디버깅 및 코드 수정이 쉬움.
5. 실제 예시:
요청: 특정 사용자의 프로필을 가져오는 API
- Controller:
클라이언트의 요청을 받고 적절한 Service를 호출. - Service:
사용자 데이터 조회 로직 수행(DB에서 조회).
예시:
// Controller
exports.getUserProfile = async (req, res) => {
const userId = req.params.id;
try {
const profile = await userService.getUserProfile(userId);
res.status(200).json(profile);
} catch (error) {
res.status(500).json({ error: error.message });
}
};
// Service
exports.getUserProfile = async (userId) => {
const user = await User.findById(userId);
if (!user) {
throw new Error('User not found');
}
return { name: user.name, email: user.email };
};
요약
- Controller는 클라이언트와 상호작용, Service는 실제 처리를 담당.
- 분리함으로써 코드의 유지보수와 재사용성이 향상됨.