모든 개발자가 따라야 할 백엔드 설정
Source: Dev.to

소개
백엔드 코드를 작성하기 전에, 확장성, 디버깅, 협업을 더 원활하게 도와주는 깔끔하고 체계적인 설정을 갖추는 것이 매우 중요합니다.
다음은 주요 6가지 레이어입니다:
- 라우트
- 컨트롤러
- 미들웨어
- 서비스
- 레포지토리
- 데이터베이스
라우트 – 진입점
라우트는 특정 요청이 서버에 도달했을 때 어떤 함수가 실행되어야 하는지를 정의합니다. HTTP 메서드와 URL을 컨트롤러에 매핑합니다.
router.post("/signup", userController.signup);
router.get("/profile", authMiddleware, userController.getProfile);
라우트는 얇고 깔끔해야 합니다. 로직을 포함하지 않으며, 요청이 어디로 가야 하는지만 결정합니다. 라우트를 백엔드의 로드맵이라고 생각하세요.
컨트롤러 – 요청 핸들러
컨트롤러가 수행하는 일:
- 요청 데이터 읽기 (
req.body,req.params,req.query) - 응답 전송 (
res.json,res.status) - 서비스 레이어 호출
컨트롤러가 하지 말아야 할 일:
- 비즈니스 로직 포함
- 데이터베이스에 직접 접근
- 비밀번호 해시 처리
- 비즈니스 규칙 계산
컨트롤러를 리셉션 직원에 비유하면, 요청을 받고 응답을 전달하는 역할을 합니다.
Middleware – The Gatekeepers
미들웨어는 컨트롤러보다 먼저 실행됩니다. 다음과 같은 용도로 사용됩니다:
- Authentication (JWT verification)
- Logging
- Input validation
- Rate limiting
- Error handling
router.get("/profile", authMiddleware, userController.getProfile);
요청은 컨트롤러에 도달하기 전에 미들웨어를 통과해야 합니다. 미들웨어를 공항의 보안 검사에 비유해 보세요.
Services – The Brain of the Application
This is where your real logic lives. Services handle:
- 비즈니스 규칙
- 데이터 변환
- 워크플로우 결정
- 여러 저장소의 오케스트레이션
exports.signup = async ({ email, password }) => {
const existingUser = await userRepository.findByEmail(email);
if (existingUser) {
throw new Error("User already exists");
}
const hashedPassword = await bcrypt.hash(password, 10);
return await userRepository.createUser(email, hashedPassword);
};
Think of services as the decision‑maker.
Repository – 데이터 액세스 레이어
Repository는 다음을 담당합니다:
- 데이터베이스와 통신
- 쿼리 실행
- 원시 데이터 반환
It does NOT:
- 비즈니스 규칙 결정
- 로직 검증
exports.findByEmail = async (email) => {
return db("users").where({ email }).first();
};
Repository는 데이터베이스에 대한 추상화입니다. PostgreSQL에서 MongoDB로 전환하더라도 변경되어야 하는 것은 레포지토리 레이어뿐입니다. 레포지토리를 애플리케이션과 데이터베이스 사이의 번역가로 생각하세요.
데이터베이스 – 스토리지 엔진
This is your:
- PostgreSQL
- MySQL
- MongoDB
- Supabase
Its job is simple:
- 데이터 저장
- 데이터 검색
- 무결성 유지
It does not care about HTTP, business logic, or application rules; it only stores information.
전체 요청 흐름
- 사용자가 가입합니다.
- 요청이 Route에 도달합니다.
- Middleware가 토큰/입력을 검증합니다.
- Controller가 요청을 받습니다.
- Controller가 Service를 호출합니다.
- Service가 비즈니스 로직을 적용합니다.
- Service가 Repository를 호출합니다.
- Repository가 Database와 통신합니다.
- 응답이 체인을 거슬러 올라갑니다.
Database → Repository → Service → Controller → Client
깨끗함. 예측 가능함. 확장 가능.
🧠 간단한 사고 모델
어디에 속하는지 헷갈릴 때는 다음과 같이 물어보세요:
- HTTP를 처리하나요? → Controller
- 검증/인증/로그를 수행하나요? → Middleware
- 비즈니스 로직인가요? → Service
- 데이터베이스 쿼리인가요? → Repository
- 스토리지인가요? → Database
- 엔드포인트를 컨트롤러에 매핑하나요? → Route
이 구조는 로버트 C. 마틴의 Clean Architecture에서 대중화된 아키텍처 원칙에서 영감을 받았으며, 실용적인 백엔드 애플리케이션을 위해 단순화되었습니다.