이 글에서는 DAO와 Repository의 차이점, 역할 분배, 코드 예제를 통해 Layered Architecture에서 두 개념을 어떻게 활용해야 하는지 설명하겠습니다. 또한, 빠른 개발을 위해 DAO 없이 Repository만 사용해도 되는 경우와, 장기적으로 DAO를 활용하는 것이 왜 좋은 설계인지도 다루겠습니다.
DAO는 데이터베이스와의 직접적인 상호작용을 담당하는 계층입니다. 즉, SQL 쿼리를 실행하거나 ORM을 사용하여 데이터를 조회, 추가, 수정, 삭제하는 역할을 수행합니다.
DAO의 주요 특징:
데이터베이스와 직접 소통 (SQL/ORM 사용)
단순한 CRUD 연산 수행 (SELECT, INSERT, UPDATE, DELETE)
비즈니스 로직을 포함하지 않음 (오직 데이터 조작만 담당)
DAO를 호출하여 데이터를 가져오고 조합
여러 DAO를 사용할 수 있음
비즈니스 로직을 포함하지 않지만, 도메인 규칙 적용 가능
데이터 가공 후 Service 계층에 전달
현실적으로 빠르게 개발해야 하는 상황에서는 DAO 없이 Repository만 사용해도 큰 문제가 없습니다.
초기 개발 단계에서 DAO와 Repository를 나누는 것은 오히려 개발 속도를 저하시킬 수 있기 때문입니다.
프로젝트가 작거나 단순한 CRUD 위주인 경우, 굳이 DAO를 분리하지 않아도 관리가 가능함
빠르게 MVP를 개발하고, 빠르게 사용자 피드백을 반영하는 것이 더 중요할 수 있음
단일 Repository에서 직접 데이터베이스 조작을 하면서 비즈니스 로직을 추가해도 큰 부담이 없음
import { db } from "../config/db";
import { users } from "../schema/users";
import { eq } from "drizzle-orm";
export class UserRepository {
static async findById(userId: number) {
return await db.select().from(users).where(eq(users.id, userId));
}
static async createUser(name: string, email: string) {
return await db.insert(users).values({ name, email }).returning();
}
}
위처럼 DAO 없이 Repository에서 직접 데이터베이스를 조작하면, 빠르게 개발이 가능합니다.
초기에는 Repository만으로도 충분하지만, 프로젝트가 커지고 유지보수성이 중요해질 때는 DAO를 도입하는 것이 좋습니다.
데이터베이스 변경에 유연함: ORM이나 데이터베이스 드라이버가 변경될 때, DAO만 수정하면 됨
테스트가 용이함: DAO는 단위 테스트를 하기 쉬우며, Repository와 분리하면 Mocking이 쉬워짐
비즈니스 로직과 DB 액세스를 분리: Repository에서 데이터 조합이나 도메인 로직을 수행하고, DAO는 단순한 CRUD만 담당
코드의 일관성 유지: 모든 데이터 액세스 코드가 한 곳(DAO)에 집중되므로 가독성이 향상됨
아래처럼 DAO를 분리하면, Repository는 단순히 데이터를 조합하는 역할에 집중할 수 있습니다.
import { UserDAO } from "../dao/UserDAO";
export class UserRepository {
static async getUserWithDetails(userId: number) {
const user = await UserDAO.findById(userId);
if (!user) return null;
const userWithDetails = {
...user,
isPremium: user.email.endsWith("@premium.com"),
};
return userWithDetails;
}
}
이제 Repository는 단순한 데이터 변환만 담당하고, 데이터베이스 액세스는 DAO가 처리하므로, 역할이 분명해집니다.
빠르게 개발할 때는 DAO 없이 Repository에서 직접 데이터베이스를 조작해도 된다.
하지만 프로젝트가 커지고 유지보수성이 중요해지면, DAO를 활용하는 것이 좋은 설계이다.
DAO를 도입하면 데이터베이스 변경에 유연하게 대응할 수 있고, 테스트가 쉬워지며, 코드의 일관성이 유지된다.
즉, MVP 단계에서는 빠르게 Repository만 사용하고, 점진적으로 DAO를 도입하는 것이 현실적인 접근법이다.
이렇게 계층을 나누면 코드의 가독성과 유지보수성이 크게 향상됩니다. Express 기반으로 Layered Architecture를 설계할 때, DAO와 Repository의 역할을 상황에 따라 적절히 선택하는 것이 중요합니다!