
최근 Board와 Board를 상속받은 VotePost(게시글의 타입 중 하나)를 작성하면서 두 가지 설계 방식에 대해 고민했습니다. 각 방식의 장단점과 해결 방안을 정리해보았습니다.
Board는 일반 게시글을 나타내고, VotePost는 Board를 상속받아 투표 기능이 추가된 특수한 게시글입니다. 이때, VotePost를 생성하는 방법에 대해 두 가지 설계 방식을 고민했습니다.
VotePost 생성 시 Board와 VotePost의 모든 필드를 한 번에 받아서 처리합니다.
장점:
클라이언트가 한 번의 API 호출로 모든 작업을 처리할 수 있습니다.
구현이 간단하고 복잡도가 낮습니다.
단점:
Board와 VotePost가 강결합되어 확장성이 떨어집니다.
새로운 게시글 타입이 추가될 때마다 API를 수정해야 합니다.
Board 생성 API와 VotePost 생성 API를 분리합니다.
장점:
Board와 VotePost가 독립적으로 확장될 수 있습니다.
관심사가 분리되어 유지보수가 용이합니다.
단점:
클라이언트가 두 번의 API 호출을 해야 합니다.
API 호출 순서를 고려해야 합니다 (Board 생성 → VotePost 생성).
두 방식의 문제점을 해결하기 위해 다음과 같은 방안을 고민했습니다.
확장성 향상: VotePost 생성 로직을 유연하게 설계하여, 새로운 게시글 타입이 추가되더라도 쉽게 확장할 수 있도록 합니다.
DTO 분리: VotePostRequestDTO에서 Board와 VotePost의 필드를 분리하여, 각각의 도메인 로직을 명확히 구분합니다.
public class VotePostReques {
private BoardRequest boardRequest;
// votepost 생성에 필요한 필드
}
서버에서 검증: VotePost 생성 API에서 Board가 존재하는지 먼저 검증합니다. 만약 Board가 없으면 404 Not Found를 반환합니다.
클라이언트에서 재시도: 클라이언트가 404 응답을 받으면, Board 생성 API를 먼저 호출한 후 VotePost 생성 API를 재시도합니다.
javascript
// 클라이언트 측 재시도 로직
async function createVotePost(boardId, votePostData) {
try {
const response = await api.createVotePost(boardId, votePostData);
return response;
} catch (error) {
if (error.status === 404) { // Board가 존재하지 않음
await api.createBoard({ id: boardId });
return await api.createVotePost(boardId, votePostData); // 재시도
}
throw error;
}
}
트랜잭션 사용: Board와 VotePost를 한 번에 생성하는 통합 API를 제공합니다. 이 API는 하나의 트랜잭션으로 동작하여 데이터 일관성을 보장합니다.
java
@Transactional
public VotePost createBoardWithVotePost(BoardRequestDTO boardRequest, VotePostRequest votePostRequest) {
Board board = boardService.createBoard(boardRequest);
return votePostService.createVotePost(votePostRequest);
}
이벤트 기반 아키텍처: VotePost 생성 요청이 들어오면, Board가 존재하지 않을 경우 Board를 생성하는 이벤트를 발행합니다. 이벤트를 통해 Board가 생성된 후 VotePost를 생성합니다.
단일 API 방식
간단한 시스템이나 초기 단계에서 적합합니다. 확장성을 고려하여 DTO와 로직을 유연하게 설계해야 합니다.
분리된 API 방식
복잡한 시스템이나 확장성이 중요한 경우 적합합니다. API 호출 순서와 데이터 일관성을 위해 서버 측 검증 또는 트랜잭션을 사용합니다.
참고 자료
DDD (Domain-Driven Design)
https://en.wikipedia.org/wiki/Domain-driven_design
REST API Best Practices
https://restfulapi.net/