개발/문제 해결 8

kotlin + spring boot 프로젝트에서 DTO 검증 체크리스트

1. Web 요청 모델과 Service 요청 모델을 분리했는가?spring-boot-starter-validation이 표현 계층 하위에서 필요한지 생각해 보기(domain이나 application...등등에서 불필요함!)data class ReserveProductWebRequest( .... ) { fun mapToServiceRequest(): ReserveProductRequest { return ReserveProductRequest( shopId, products.map { it.mapToServiceObject() }, LocalDateTime.parse(reservedAt) ) } } 2. 중첩해서 검증하고 싶다면? 중첩 DTO의 예시는 다음과 같음 ReserveProductWebReque..

레거시 코드를 헥사고날 아키텍처로 전환(Final) - 회원 도메인에서 웹, 인증 어댑터 분리

레거시 코드를 헥사고날 아키텍처로 전환(2)과 이어지는 글입니다 1단계, 컨트롤러 패키지 위치 변경 기존에 존재하는 컨트롤러의 위치를 adapter 내부로 이동시켰다. 2단계, 컨트롤러에서 필요한 기존 userService에 대한 의존성 제거 @RequestMapping("/user") @InboundAdapter @RequiredArgsConstructor public class UserController { private final JwtService jwtService; private final RegisterUserUseCase registerUserUseCase; private final UserWithdrawalUseCase userWithdrawalUseCase; private final R..

레거시 코드를 헥사고날 아키텍처로 전환(2) - 회원 도메인에서 읽기 전용 유스 케이스 분리, 영속성 어댑터 만들기

레거시 코드를 헥사고날 아키텍처로 전환(1)과 이어지는 글입니다. 1단계, 영속성 어댑터를 만들자 영속성 어댑터의 위치는 다음과 같다. 기존에 존재하는 UserRepository를 변경하기 이전에 나는 도메인 엔티티와 JPA 엔티티를 분리하기로 했다. 관련해서 "만들면서 배우는 클린 아키텍처"라는 책에서 다음과 같은 말을 인용해 봤다. 영속성 측면과 타협 없이 풍부한 도메인 모델을 생성하고 싶다면 도메인 모델과 영속성 모델을 매핑하는 것이 좋다. JPA 엔티티에는 기본 생성자가 필요하다. 또한 영속성 레이어에서는 성능 측면에서 @ManyToOne 관계를 설정하는 것이 적합할 수 있지만, 도메인 모델에서는 반대가 되는 것이 더욱 객체지향적일 수 있다. 예를 들어, 팀(야구)이라는 객체가 있다. 4번 타자와..

레거시 코드를 헥사고날 아키텍처로 전환(1) - 회원 도메인에서 쓰기 전용 유스 케이스 분리

들어가는 말 현재 만들고 있는 사이드 프로젝트인 아르티에서 안 좋은 신호들을 발견했던 걸 정리해 둔 글이 있다. 아르티 아키텍처 디자인에 대해서 끄적에서는 주로 뚱뚱한 서비스 클래스를 어떻게 분리할 것인가에 대해 다룬다. 글을 쓴 이후에도 문제를 해결하기 위해서 여러 글을 찾아봤는데, 이때 헥사고날 아키텍처라는 것을 알게 됐다. 현재 팀원과 나는 "만들면서 배우는 클린 아키텍처"라는 책을 읽고, 프로젝트에 적용 중이다. 이번 주에는 내가 회원 도메인을 개선하기로 맡았는데, 과정을 기록하고 팀원에게 공유하는 것이 포스팅의 목적이다. 이외에도 쿼리나 테스트 코드를 개선하고 싶었는데 이번 기회에 시도해 봐야겠다. (기존 테스트 코드는 모든 스프링 빈을 컨테이너에 담아서 실행하기 때문에 시간이 오래 걸릴뿐더러,..

아르티 아키텍처 디자인에 대해서 끄적

1. 신호 이 고민은 유효성 검사 로직에서 출발한다. 유효성 검사 로직이 많아지다 보니 처음에는 validator class를 분리해야 하나 생각했다. 하지만 그것보다 근본적인 문제가 있었다. 전시 서비스에서 카테고리 서비스를 참조해서 카테고리를 조회해야 하는데 이때 자신이 사용하는 것보다 더욱 많은 기능을 가져오게 된다. 왜 그럴까? 2. 원인과 문제 원인 원인은 서비스 클래스가 너무 많은 일을 하고 있는 것이다. 이는 SRP 위반이라고 할 수 있다. 따라서 서비스 클래스의 길이가 점점 커진다. 문제점 서비스 클래스가 길어지면 기능을 추가할 때마다 코드를 깔끔하게 유지하기 어렵다. 전형적인 뚱뚱한 클래스로 Fan-In 문제가 발생한다. 예컨대 전시 서비스, 카테고리 컨트롤러가 의존함 테스트 코드가 길어..

Typeorm 식별 관계 문제

typeorm을 사용해서 데이터베이스를 구축하는 중에서 식별 관계를 구축하는 과정에서 만난 문제를 해결하는 과정이 담긴 짧은 글 회원과 트레이너가 1대 1로 매칭 되어 트레이닝이 성사된다. 그리고 이 둘이 기본키에 참여하므로 식별 관계이다. 또한 트레이닝이 있어야 기록(식단이나 운동 영상)이 존재하기 때문에 기록은 약 엔티티이다. 다시 말하자면, 기록은 그 자체로서 의미를 가질 수 없다. 왜냐하면 현재 하고 있는 프로젝트 기획에서 트레이닝이 성립돼야 기록을 작성할 수 있기 때문이다. 약한 엔티티는 엔티티를 고유하게 식별하기 위해서 다른 엔티티 타입으로부터 키 속성을 가져온다. 문제 식별관계로 하자니 트레이닝과 기록이 one to many 이기 때문에 결국 기록의 기본 키 집합에 새로운 칼럼을 추가해야 한..