개요
Repository Pattern은 데이터 접근을 추상화하여 비즈니스 로직과 데이터 저장소 간의 의존성을 줄이는 디자인 패턴입니다. 이 패턴은 데이터 소스에 대한 CRUD(Create, Read, Update, Delete) 작업을 캡슐화하여 코드의 유지보수성과 테스트 용이성을 향상시킵니다.
주요 개념
- Repository: 데이터에 대한 CRUD 작업을 수행하는 인터페이스 및 구현체를 정의합니다.
- Entity: 데이터베이스의 테이블과 매핑되는 클래스입니다.
- Unit of Work: 여러 리포지토리에서 발생하는 데이터 변경 작업을 하나의 트랜잭션으로 묶는 패턴입니다.
장점
- 분리된 관심사: 비즈니스 로직과 데이터 접근 로직이 분리되어 코드가 더 깔끔해집니다.
- 테스트 용이성: Mock 객체를 사용해 리포지토리를 대체함으로써 단위 테스트가 쉬워집니다.
- 유연성: 데이터 저장소를 쉽게 교체할 수 있습니다. 예를 들어, SQL 데이터베이스에서 NoSQL로 변경할 때 코드 수정이 최소화됩니다.
사용 예시
1. 환경 설정
Node.js와 MongoDB를 사용할 경우, 먼저 필요한 패키지를 설치합니다.
npm install express mongoose
2. 모델 정의
models/Product.js 파일을 만들어 MongoDB의 Product 모델을 정의합니다.
// models/Product.js
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
price: { type: Number, required: true },
description: { type: String },
});
const Product = mongoose.model('Product', productSchema);
module.exports = Product;
3. 리포지토리 정의
repositories/ProductRepository.js 파일을 만들어 리포지토리를 정의합니다.
// repositories/ProductRepository.js
const Product = require('../models/Product');
class ProductRepository {
async getById(id) {
return await Product.findById(id);
}
async getAll() {
return await Product.find();
}
async add(productData) {
const product = new Product(productData);
return await product.save();
}
async update(id, productData) {
return await Product.findByIdAndUpdate(id, productData, { new: true });
}
async delete(id) {
return await Product.findByIdAndDelete(id);
}
}
module.exports = ProductRepository;
4. 서비스 정의
services/ProductService.js 파일을 만들어 비즈니스 로직을 포함하는 서비스를 정의합니다.
// services/ProductService.js
const ProductRepository = require('../repositories/ProductRepository');
const productRepository = new ProductRepository();
class ProductService {
async getProductById(id) {
return await productRepository.getById(id);
}
async getAllProducts() {
return await productRepository.getAll();
}
async createProduct(productData) {
return await productRepository.add(productData);
}
async updateProduct(id, productData) {
return await productRepository.update(id, productData);
}
async deleteProduct(id) {
return await productRepository.delete(id);
}
}
module.exports = ProductService;
5. 서버 설정
app.js 파일을 만들어 Express.js 서버를 설정하고 API 엔드포인트를 정의합니다.
// app.js
const express = require('express');
const mongoose = require('mongoose');
const ProductService = require('./services/ProductService');
const app = express();
const productService = new ProductService();
app.use(express.json());
// MongoDB 연결
mongoose.connect('mongodb://localhost:27017/mydatabase', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// API 엔드포인트 정의
app.get('/products/:id', async (req, res) => {
const product = await productService.getProductById(req.params.id);
if (!product) {
return res.status(404).json({ message: 'Product not found' });
}
res.json(product);
});
app.get('/products', async (req, res) => {
const products = await productService.getAllProducts();
res.json(products);
});
app.post('/products', async (req, res) => {
const newProduct = await productService.createProduct(req.body);
res.status(201).json(newProduct);
});
app.put('/products/:id', async (req, res) => {
const updatedProduct = await productService.updateProduct(req.params.id, req.body);
if (!updatedProduct) {
return res.status(404).json({ message: 'Product not found' });
}
res.json(updatedProduct);
});
app.delete('/products/:id', async (req, res) => {
await productService.deleteProduct(req.params.id);
res.status(204).send();
});
// 서버 시작
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
결론
JavaScript에서의 Repository Pattern은 비즈니스 로직과 데이터 접근 로직을 분리하여 코드의 가독성과 유지보수성을 높입니다. 이 패턴을 사용하면 데이터 저장소의 변경이 용이하며, 테스트와 확장이 쉬워집니다. 이 예시는 Node.js 환경에서 MongoDB를 사용할 때의 기본적인 구현 방법을 보여줍니다.
'TIL' 카테고리의 다른 글
OSI 7계층 응용 계층 (Application Layer)에 대하여 (간단 소개) (0) | 2024.09.24 |
---|---|
Status Code 종류별로 한줄로 설명하기 - 틀린 부분 또는 추가할 부분 지적 O (0) | 2024.09.24 |
초보자를 위한 깃허브 팀원끼리 연결, PullRequest, Merge 하는 법 (feat. SubBranch, VSCODE) (0) | 2024.09.19 |
OSI 7계층 중 전송 계층에 대하여 (0) | 2024.09.11 |
에러 핸들러와 미들웨어에 관하여 & 데이터 유효성 검증 라이브러리 Joi (2) | 2024.09.10 |