
API Composition PatternAPI 컴포지션 패턴
API 컴포지션 패턴(API Composition Pattern)은 여러 마이크로서비스의 데이터를 하나의 API 응답으로 결합하는 패턴이다. 각 서비스가 독립 DB를 가질 때 JOIN 쿼리를 대체한다.
문제
모놀리스: SELECT o.*, u.name, p.title FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id
마이크로서비스: 각 서비스가 별도 DB
→ DB JOIN 불가
→ API 컴포지션으로 해결구현 패턴
typescript
// API 게이트웨이에서 컴포지션
async function getOrderDetails(orderId: string) {
// 병렬로 각 서비스 호출
const [order, user, product] = await Promise.all([
orderService.getOrder(orderId),
userService.getUser(order.userId),
productService.getProduct(order.productId),
]);
// 클라이언트에게 통합 응답
return {
orderId: order.id,
status: order.status,
customerName: user.name,
productTitle: product.title,
amount: order.amount,
};
}GraphQL 활용
graphql
# Schema (API 게이트웨이)
type Order {
id: ID!
status: String!
customer: User! # UserService 호출
product: Product! # ProductService 호출
amount: Float!
}
# Resolver
const resolvers = {
Order: {
customer: async (order) =>
userService.getUser(order.userId),
product: async (order) =>
productService.getProduct(order.productId),
},
};
# 클라이언트 쿼리 (한 번의 요청)
query {
order(id: "123") {
status
customer { name email }
product { title price }
}
}성능 최적화: DataLoader
javascript
// N+1 문제 해결: 배치 로딩
const userLoader = new DataLoader(async (userIds) => {
const users = await userService.getUsersByIds(userIds);
return userIds.map(id => users.find(u => u.id === id));
});
// 여러 주문의 사용자 정보를 한 번의 배치 요청으로CQRS와의 결합
복잡한 조회 시: API 컴포지션 대신
CQRS Read Model 사용
이벤트 기반으로 미리 조합된 뷰 유지:
Order 생성 이벤트 → OrderView 테이블에 비정규화 저장
조회 시 단순 SELECT