테이블 상속 구현방식

ksngh·2025년 3월 7일

자바스프링

목록 보기
7/8

Board와 VotePost 설계 방식

최근 Board와 Board를 상속받은 VotePost(게시글의 타입 중 하나)를 작성하면서 두 가지 설계 방식에 대해 고민했습니다. 각 방식의 장단점과 해결 방안을 정리해보았습니다.

문제 상황

Board는 일반 게시글을 나타내고, VotePost는 Board를 상속받아 투표 기능이 추가된 특수한 게시글입니다. 이때, VotePost를 생성하는 방법에 대해 두 가지 설계 방식을 고민했습니다.

1. 단일 API 방식

VotePost 생성 시 Board와 VotePost의 모든 필드를 한 번에 받아서 처리합니다.

  • 장점:
    클라이언트가 한 번의 API 호출로 모든 작업을 처리할 수 있습니다.
    구현이 간단하고 복잡도가 낮습니다.

  • 단점:
    Board와 VotePost가 강결합되어 확장성이 떨어집니다.
    새로운 게시글 타입이 추가될 때마다 API를 수정해야 합니다.

2. 분리된 API 방식

Board 생성 API와 VotePost 생성 API를 분리합니다.

  • 장점:
    Board와 VotePost가 독립적으로 확장될 수 있습니다.
    관심사가 분리되어 유지보수가 용이합니다.

  • 단점:
    클라이언트가 두 번의 API 호출을 해야 합니다.
    API 호출 순서를 고려해야 합니다 (Board 생성 → VotePost 생성).

해결 방안

두 방식의 문제점을 해결하기 위해 다음과 같은 방안을 고민했습니다.

1. 단일 API 방식의 문제점 해결

확장성 향상: VotePost 생성 로직을 유연하게 설계하여, 새로운 게시글 타입이 추가되더라도 쉽게 확장할 수 있도록 합니다.

DTO 분리: VotePostRequestDTO에서 Board와 VotePost의 필드를 분리하여, 각각의 도메인 로직을 명확히 구분합니다.

public class VotePostReques {
    private BoardRequest boardRequest;
    // votepost 생성에 필요한 필드
}

2. 분리된 API 방식의 문제점 해결

문제 1: API 호출 순서

서버에서 검증: 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;
    }
}
문제 2: 데이터 일관성

트랜잭션 사용: Board와 VotePost를 한 번에 생성하는 통합 API를 제공합니다. 이 API는 하나의 트랜잭션으로 동작하여 데이터 일관성을 보장합니다.

java
@Transactional
public VotePost createBoardWithVotePost(BoardRequestDTO boardRequest, VotePostRequest votePostRequest) {
    Board board = boardService.createBoard(boardRequest);
    return votePostService.createVotePost(votePostRequest);
}

3. 추가 고려사항

이벤트 기반 아키텍처: 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/

profile
백엔드 개발자입니다.

0개의 댓글