프로젝트를 시작한 지 일주일이 조금 넘어간다. 초반 3일 정도 동안은 팀원들과 ERD 설계, 요구사항 정리, 깃 컨벤션 정리 등등을 했고, 본격적으로 각 도메인을 맡아 개발을 한지는 막 일주일이 된 것 같다.
내가 메인으로 맡은 쿠폰 도메인은 크게 발급 수량 제한이 없는 일반 쿠폰과, 선착순 쿠폰 이벤트를 위한 선착순 쿠폰으로 나눠진다. 그리고 쿠폰 도메인은 쿠폰 자체의 발급을 위한 관리자용 쿠폰 CRUD, 발급된 쿠폰 내역을 유저마다 관리하는 쿠폰 발급 CRD 기능이 존재한다.
이번 포스팅에서는 위에서 설명한 쿠폰 발급 로직을 설계하며 고민했던 사항들과, 고민 끝에 왜 이렇게 결정했는지 기술적 의사 결정에 대한 설명을 적어보려 한다.
🔎고민
일반 쿠폰과 선착순 쿠폰 로직의 API 엔드포인트를 따로 두는 게 맞을까?
- 현재 일반 쿠폰 발급 엔드포인트
/**
* 쿠폰 발급
*/
@PostMapping("/issue")
public ResponseEntity<ApiResponseDto<CouponIssuedResponseDto>> issueCoupon(@RequestBody CouponIssuedRequestDto request) {
CouponIssuedResponseDto issued = couponIssuedService.issueCoupon(request);
return ResponseEntity.ok(new ApiResponseDto<>(HttpStatus.OK, "쿠폰이 발급되었습니다.", issued));
}
✏️의사 결정
따로 두자!
✏️사유
일반 쿠폰 발급 로직과 선착순 쿠폰 발급 로직을 각각 별도의 API 엔드포인트로 분리하기로 결정했다. 분리 하지 않았을 때 보다, 분리 할 때의 이점이 내가 생각했을 때 더 많았기 때문이다.
분리 하지 않을 시 이점
- 중복 코드의 최소화
일반 쿠폰과 선착순 쿠폰 발급 로직이 동일한 엔드포인트에서 처리되면, 중복되는 코드(ex. 쿠폰 유효성 검사, 사용자 인증 등)가 줄어들어 코드 중복을 최소화 시킬 수 있을 것이다. - 단순한 확장
추후 새로운 유형의 쿠폰이 추가되면, 별도의 엔드포인트를 만들 필요 없이 기존 엔드포인트의 로직을 확장하면 된다.
분리 시 이점
- 비즈니스 로직의 명확한 구분
선착순 쿠폰 발급과 일반 쿠폰 발급은 서로 다른 비즈니스 로직을 가질 가능성이 높았다. 아마도, 선착순 쿠폰 발급은 제한된 수량을 처리하기 때문에 동시성 문제를 해결해야 할 수 있다. (이제 해결 해야함ㅎ) 반면 일반 쿠폰 발급은 이런 제약이 거의 없을 것이다. - 유지 보수의 용이성
위와 같은 이유로, 만약 두 로직이 하나의 API에 섞이게 되면 다른 로직에 영향을 줄 수도 있다고 생각했다. 또한 각각의 발급 로직이 변경될 때 해당 로직에만 집중해서 수정할 수도 있다. - 테스트 작성의 용이성
각 엔드포인트에 대한 테스트 케이스를 별도로 작성해서 더 세분화된 테스트가 가능하다. API가 한 개면 테스트를 작성할 때 훨씬 복잡해 질 것 .. - 확장성
향후 각 발급 로직에 추가적인 기능이나 정책이 필요할 때, 각각의 엔드포인트에서 쉽게 확장할 수 있다. 또한 특정 발급 로직에 대한 성능 최적화나 개선 작업을 독립적으로 수행할 수 있다. - 보안 및 권한 관리
위와 비슷한 이유로, 각 엔드포인트에 대해 서로 다른 권한을 설정하거나 보안 정책을 적용하기도 용이할 수 있다. (ex. 선착순 쿠폰 발급 특정 시간에만 허용하기)
이러한 이유들로 API 엔드포인트를 분리하는 것으로 결정했다. 비즈니스 로직을 구분하는 것과 유지보수의 용이성이 분리의 가장 큰 이유였지만, 중복 코드 없이 객체지향적으로 설계하느냐 vs 비즈니스 로직 분리에 힘쓰느냐 이런 고민들을 하게 되는 것 같다. 더 공부하고 경험 쌓는 것만이 답인 것 같음 😀
자 이제 개발하러 가잣!
'Project > MSA 프로젝트' 카테고리의 다른 글
[트러블슈팅] '선착순 쿠폰 발급' 로직 - Redis를 통한 동시성 문제 해결 (2/2) (0) | 2024.06.30 |
---|---|
[트러블슈팅] '선착순 쿠폰 발급' 로직 - 동시성 문제 발생 (w/ Race Condition) (1/2) (2) | 2024.06.30 |
[프로젝트][MSA] API Gateway 작성으로 모듈 별 연결하기 (0) | 2024.06.25 |
[프로젝트] 인텔리제이 깃 클론/pull 후 모듈 인식 불가 해결 (0) | 2024.06.13 |
[프로젝트] 모놀리식과 MSA: MSA 구조 채택 이유 (0) | 2024.06.13 |