8월 모두의 텃밭 회고를 바탕으로 시작되는 글입니다.
2024년 1월 광고를 중심으로 본격적으로 유저를 받아보기 위한 작업에 돌입했다.
기능 확장 및 사용성을 고려하여 새로운 디자이너를 모집했다.
그리고 기존에 계셨던 이라님과 진겸님이 함께 했고
새롭게 데브코스에서 만났던 프론트 희석님과 백엔드 도연님이 합류했다.
기능 확장하기에 앞서
나는 위 회고 느꼈던 문제점들을 먼저 해결해야 겠다고 생각했다.
코드적인 문제점들은 아래와 같다.
코드적인 문제점들을 떠나 위 회고에 적었던 시도해 볼만한 점들은 아래와 같다.
그래서 나는 2차 MVP를 진행하기 전에 문제점들을 먼저 해결해보기로 했다.

원래는 왼쪽과 같이 컨트롤러의 DTO와 서비스의 DTO가 함께 쓰였다.
이는 레이어드 아키텍처 구조의 의존성 흐름을 해치고 있었기 때문에
오른쪽과 같이 프레젠테이션 레이어 -> 애플리케이션 레이어 -> 데이터 접근 레이어 순으로 가도록
DTO를 레이어드 별로 분리하는 작업을 하게 되었다.

컨트롤러는 단순히 클라이언트에서 받은 요청값을 서비스에 전달하고 서비스로부터 받은 응답을 클라이언트에게 전달하는 역할만을 해야한다고 생각한다.
그러나 기존의 코드는 왼쪽과 같이 두 가지 문제가 있었다.
따라서 기존 코드에 존재했던 parsing에 대한 작업들과 서비스에서 해결해야할 비즈니스 로직, 혹은 쿼리 조건문으로 해결할 수 있는 분기처리 등을 각 레이어드 역할에 맞게 분리하는 작업을 하게 되었다.
이전 모두의 텃밭은 테스트 코드 없이 작업했기 때문에
신규 기능을 확장하는데 다른 비즈니스 로직에 영향을 주는지 알 수 없었고 새로운 팀원이 합류되었을 때 어떤 로직으로 구현되는지 파악하기 어려웠다.

이에 따라 신규 기능 확장 이전에 기존 코드에 대한 테스트 코드를 만들어보기로 하였다.
소나 클라우드를 통해서 80%이상의 테스트 코드 커버리지 기준을 정하게 되었다.

또한 다른 프로젝트에서 테스트 코드 시간이 오래 걸려 테스트 코드 시간 최적화에 대한 필요성을 느꼈다. 그래서 모두의 텃밭에서는 스프링의 Context Caching을 이용하여 컨텍스트가 재사용되는 구조로 만들었다. 그러기 위해서는 어떤 기준으로 Cache key를 만드는지 알 필요성이 있다.
이 글에 들어가면 어떤 걸 기준으로 Cache Key 만들어 재사용이 가능한 지 나오는데 Mock Bean과 Active Pofile이 다른 경우에 새로운 Test Context가 로딩되므로 나는 하나의 클래스에서 모두 MockBean을 올려놓고 이를 상속받는 방식으로 구현하였다. 이로써 테스트 코드를 최적화할 수 있었다.

기존에 노션으로 관리되던 API 명세서는 어떤 필드가 무엇을 의미하는지 친절한 설명과 예시가 부족했다. 또한 중간에 요청값이나 응답값이 바뀌었는데 이를 반영해놓지 못해 프런트는 이미 구현해놓은 기능들을 바꿔야하는 경우도 있었다. 따라서 2차 MVP를 진행하기에 앞서서 모든 코드를 리팩토링하면서 Resc docs도 전부 작성해보기로 하였다.

기존의 코드를 보면 어떤 쿼리이든 모든 칼럼을 가져온다.
실제로 필요하지 않은 값임에도 *을 이용해서 가져오고 있다.
이 방법에는 몇 가지 단점이 있다고 생각한다.
따라서 쿼리문에 정말 필요한 칼럼명만 언급하였고 Projection을 이용해서 꺼내왔다.
똑같은 DTO를 재사용해도 될까?
API별로 DTO를 만드는게 맞는걸까?
만들었더니 너무 많은 DTO가 생성되는데?
먼저 똑같은 DTO를 재사용하는 것이 좋은 방법은 아닌거 같다.
1. 모두 다 보내고 필요한 것들만 프론트에서 뽑아서 쓰면되지 않을까라고 생각할 수 있지만 그렇게 되면 위와 같이 Select * 쿼리가 만들어진다.
2. 정말 필요한 것만 보내는 두 API 요청의 응답이 같으면 같이 사용해도 되지 않을까? 처음에는 그렇게 생각할 수 있겠지만 생각보다 사용자의 요청은 빈번하게 바뀐다. 사용자의 요청사항이 바뀌었는데 나랑 같은 DTO를 사용하는 API까지 그 영향이 퍼지는 걸 방지하도록 API 요청별 DTO를 분리하는 것이 좋아 보인다.
3. 너무 많은 DTO가 만들어 졌다면 DTO 내부에 패키지를 request, response로 나누어 분리하는 것도 하나의 방법이고 record 내부의 record를 만드는 것도 하나의 방법이 될 수 있다.
따라서 나는 위와 같은 이유로
계속 재사용되던 GardenResponse를 API 별로 분리하는 작업을 하였다.

보면 GardenController의 모든 요청은 단 하나의 DTO GardenResponse로 간다.
왼쪽의 그림보다 더 많은 API가 아래 존재하는데 모두 GardenResponse로 간다.
이를 개선하여 오른쪽과 같이 API마다 다른 DTO를 반환하도록 변경하였다.

1차 MVP가 끝나고 각자 최종 회고를 적는 시간을 가졌다.
2차 MVP를 진행하며 회고 시간에 나왔던 부분들을 모두 반영하려고 하였다.
따라서 2차 MVP를 진행할 때는 아래와 같은 항목을 모두 지켜나가고자 노력하고 있다.

