주특기 주차를 마치고 프론트엔드와 처음으로 협엽하는 6주차 과정이 끝났다. 단순히 데이터의 흐름을 통제하고 가공하는 것을 주특기 주차 때 배웠다면, 6주차에서는 작지만 하나의 서비스를 만들고 이를 타인과 함께 소통하는 것이 얼마나 중요한지 많이 느낄 수 있었다. 프론트엔드와의 통신은 CORS, 데이터 변수명, 응답 형태 등 고려할 것이 많지만 그에 못지 않게 어떤 것을 구현하고 이에 관한 끊임없는 의견교류가 중요했던 것 같다. 특히 디테일하고 자세한 API의 필요성을 느낄 수 있었고 이를 바탕으로 다음 협업에서는 6주차에서 발생했던 실수를 반복하지 않을 것이다.
https://github.com/Goonerd17/GG/tree/dev
GitHub - Goonerd17/GG
Contribute to Goonerd17/GG development by creating an account on GitHub.
github.com
다양한 시도를 해볼 수 있었던 6주차 과제였다. 단순 CRUD를 넘어서, 페이징, 검색, S3등을 활용하며 심화된 내용을 배우며 실제 적용해보는 과정이었다. S3 부분은 아직도 좀 더 공부해야할 필요성을 느끼지만, 어쨌든 프로그래밍의 프 도 모르던 5월과 비교하면 괄목할 만한 성장인 것 같다.
팀장을 맡으면서 여러모로 신경써야할 점들을 알 수 있었던 것도 큰 수확이었다. 프론트엔드가 편리하게 데이터를 식별할 수 있는 법을 고민할 수 있었고, 빠른 배포로 프론트엔드가 얻을 수 있는 이점을 알 수 있었다. 나름 열심히 한다고 프로젝트를 본격적으로 시작한 토요일 이후 월요일에 배포를 시도했지만, 좀 더 빠르게 일요일에 배포하거나, 프론트에서 이용하는 mockData를 백엔드 측에서 우선적으로 만들어줬으면 프론트 분들이 더 쉽게 작업할 수 있었을 것 같다는 생각이 든다. 해당 부분은 개인적으로도 아쉽기도 하고 협업에 있어 배려가 얼마나 중요한지 알 수 있었기에 다음 협업에서는 꼭 이러한 포인트들을 생각하면서 프로젝트에 참여할 것이다. 협업뿐 만 아니라 백엔드 자체적인 팀원들간의 의견 조율에서도 배울 수 있는 점이 많았다. 처음에 백엔드끼리 자체적으로 나눈 역할 분담은 분명 일정안에 프로젝트를 완료하기에는 힘들 것 같다고 생각이 되었기에 기본CRUD, 좋아요 기능, 검색, 페이징, 이미지 업로드 정도를 따로 구현했다. 이 후 S3의 전반적인 기능이나, 댓글 부분의 코드 작성을 팀원분들에게 부탁했는데 처음부터 도메인으로 역할을 나눠서 진행했으면 더 생산적인 프로젝트가 되지가 않았을까 싶다. 잘 만들어보고 싶다는 개인적인 욕심이 있었기에 해당 결정들을 후회하지는 않지만 다음에는 보다 구체적으로 일정을 정해 역할 분담을 잘 해서 프로젝트를 진행해야겠다는 생각을 할 수 있었다.
이번 미니 협업 프로젝트 주차에서 고민했던 부분들
1. 예외 처리와 예외 메세지 Enum 처리
예외 처리를 좀 더 깔끔한 방식으로 진행했으면 좋겠다는 피드백을 받고 예외 메세지들을 일괄적으로 Enum으로 만든 뒤 이를 활용하였고, 기존 자바에서 제공하는 예외를 상속받아 커스텀 예외를 만들어 사용하였다. 이 과정에서 Checked Exception을 사용하게 되면 발생하는 예외의 전파와 계층의 예외 의존성을 확인할 수 있었고 이를 Unchecked Exception으로 변환하여 처리하는 방법도 익힐 수 있었다. 하지만 해당 과정에서 예외를 따로 커스텀하는 부분에 대해서는 의문이 들었는데 굳이 필요하지 않은 단순한 예외도 부수적인 클래스를 만들어 사용하는 것이 아닌가 하는 고민이 들었다. 발생하는 예외들의 속성이 모두 IllegalArgumentException이었는데 커스텀으로 처리하기보단 자바에서 제공하는 기본 예외를 사용하는 게 불필요한 코드도 줄이고 정확히 어떤 상황에서 발생할 수 있는 예외인지 직과적으로 알 수 있는 듯 했다. 물론 6주차 프로젝트는 매우 작은 규모의 프로젝트였기에 이러한 고민이 들었고 조금 더 규모 큰 프로젝트를 하게 되면 따로 커스텀이 필요한 예외들은 묶어서 하나의 커스텀 예외 클래스를 생성하는 것이 좋을 것 같다.
2. S3 사용
EC2 이후 새롭게 배우는 AWS의 S3는 생각보다 어려웠다. 객체 저장소라는 개념 자체는 이해하기 쉬웠으나 그 사용법에 대해서는 고민이 되었다. 단순히 구글에 떠돌아다니는 코드를 복사붙여넣기하기 보다는 업로드, 삭제 과정들을 분석하고 이해하고 싶었는데 다행히 팀원 분 중 한 명이 간결한 주석과 함께 S3 사용 코드를 작성하셨고 해당 코드들을 분석하면서 보다 깊게 S3에 대해서 이해할 수 있었다. 항상 느끼지만 AWS에서 제공하는 서비스들은 정말 많지만 익숙하지 않아서인지 이를 숙달하는 데에는 시간이 꽤 많이 들 것 같다. 하지만 이미지를 클라우드 저장소에 보관하여 활용하는 방식은 개인적으로 흥미로웠고, AWS가 또 어떤 다른 기능들을 제공하는지 기대된다. 인프런에서 AWS의 기초 입문 강의를 결제했는데 일요일에 시간이 된다면 해당 강의를 정독하여 탄탄한 AWS 기초를 쌓고 싶다고 생각하였다.
3. n + 1 문제와 카르테시안 곱
Post 엔티티의 List로 존재하는 Comment 엔티티를 조회할 때 n + 1 문제가 발생할 것이 예상되었으므로 이 부분에 대해서 left join fetch를 사용했다. 하지만 실제 쿼리를 날려보니 comment의 username을 조회하기 위해 user들에 대해서도 쿼리를 날리게 되어 comment를 작성한 user가 5명일 경우 6번의 쿼리가 발생하는 문제가 발생하였다. 프로젝트 막바지에 해당 문제를 확인해서 이에 대해 미리 포착하지 못한 불찰이 아쉬웠다. 하지만 최대한 빨리 해당 문제를 해결하기 위해 다양한 방법들을 시도해보았다. 처음에는 컬렉션에 join fetch를 사용하면 안 될거라고 생각했지만 혹시 모르니까 left join fetch p.commentList cl join fetch cl.user 로 작성을 했다. 우려와 달리 해당 쿼리는 정상적으로 작동하였고 쿼리 한 번으로 post의 comment, comment의 username 까지 가져올 수 있었다. 하지만 뭔가 찝찝함을 감출 수 없었는데 여러가지 상황을 가정해보면서 알게 된 것은 이러한 쿼리는 가르테시안 곱이 될 수 있다라는 것이었다. 실제 row는 10개에 불과한 데이터가 반복적인 join fetch로 인해 row가 뻥튀기 되고 20,30, 혹은 그 이상의 반복되는 row를 가져올 수 있는 상황이 발생할 수 있었다. 이는 분명 해당 row가 어마어마하게 많은 경우 데이터를 가져오는 서버측에서도 과부하가 발생할 것으로 예상되었다. 따라서 기존에 사용했던 join fetch 반복은 폐기하고 다른 방법들을 찾아보았다.
@Fetch(SUBSELECT)
@OneToMany(mappedBy = "post", cascade = ALL, orphanRemoval = true)
private List<Comment> commentList = new ArrayList<>();
구글링을 통해 @Fetch를 이용하여 컬렉션의 요소들을 서브쿼리로 이용하여 가져오는 방법을 알게 되었다. 해당 방법을 사용하면 post에 대한 쿼리 한 번, comment에 대한 쿼리 한 번(서브쿼리 이용)을 이용해 데이터를 가져올 수 있었다. 쿼리 자체는 1번에서 2번으로 늘어났지만 가지고 오는 데이터의 개수들 자체는 줄어들었기에 이러한 방식이 좀 더 효율적이라고 생각했다. 이외에도 다른 방법은 @BatchSize가 있었지만 해당 방법이 기존에 몰랐던 점이기도 해서 @Fetch방식을 이용하여 데이터를 가져왔다. 이를 통해 추가적으로 발생하는 comment의 user를 가져오면서 발생하는 n + 1 문제도 해결할 수 있었다.
결론적으로 6주차 과정은 꽤 재밌었다. 인상깊었던 점은 프론트엔드 분들이 어려움에 부딪히거나 막히는 부분이 생기면 바로 해당 문제를 해결한 분께 달려가서 해답을 얻는 것이 아닌 직접 검색하고 여러 자료들을 찾아가며 주도적으로 문제를 해결하는 과정이었다. 나 또한 그런 방식으로 공부를 하고 있기에 이 과정이 얼마나 괴롭고, 무조건 정답이라고 생각했던 코드가 이유를 알 수 없는 오류로 정상 작동하지 않을 때 느끼는 좌절감이 크다는 것을 알고 있었다. 하지만 포기하지 않고 계속 해결을 시도하면서, 결국에는 실제 구현까지 성공하였다. 이후 배포까지 완료 우리가 처음 계획했던 서비스와 거의 동일하게 구현한 모습을 보고 배울 점이 많다고 느꼈다. 남들이 보기엔 작을 수도 있겠지만, 팀원들의 노력을 옆에서 지켜본 나로써는 해당 프로젝트를 이렇게 완성시킨 것이 많은 노력이 들어갔다는 것을 알고 있었고, 때문에 더 대단하다고 느꼈다. 여러모로 좋은 경험이었고 이 경험을 통해 얻을 수 있었던 교훈들을 바탕으로 다음 프로젝트는 좀 더 완성도 있고 다양한 기능들을 만들어보고 싶다.
6주차 프로젝트 시연 영상
https://www.youtube.com/watch?v=2Cr1NRiHLuc&ab_channel=%EC%9C%A0%EC%8B%9C%ED%99%98
'프로젝트 회고 > 주차별 회고' 카테고리의 다른 글
이노베이션 10주차 실전 프로젝트 회고 3 (0) | 2023.08.20 |
---|---|
이노베이션 9주차 실전 프로젝트 회고 2 (0) | 2023.08.14 |
이노베이션 8주차 실전 프로젝트 회고 1 (0) | 2023.08.06 |
이노베이션 7주차 클론코딩 회고 (1) | 2023.07.27 |
이노베이션 3,4,5 주특기 회고 (0) | 2023.07.13 |