[CodeSquad] TODO-LIST 팀 프로젝트 후기(4.4~4.15)
레퍼지토리 주소: https://github.com/naneun/todo-list/tree/team-11
4.4 ~ 4.15
2주간 iOS 팀 (@Eddy
, @Jason
), 백엔드 팀 (@후
, 나 @Riako
) 가 한 팀을 이루어 TODO-LIST 앱 만들기를 진행했습니다. 시작 전에 걱정이 많았습니다. 단순히 혼자 기능을 구현하고 커밋하고 pr 요청하고 fetch 하는 것과는 달리 팀원들의 개발 진행 상황을 꾸준히 살피며 협력과 대화가 필요한 부분에 있어서는 의견을 조율해야하는 등 반드시 신경써야할 요소들이 프로젝트를 시작하기도 전에 떠올라 긴장이 많이 되는 상태였습니다. 마음이 놓였던 건 평소에 개인적으로 편하게 생각하는 멤버 중 하나인 @후 와 같은 팀이 되었다는 점?! 스크럼 시간에 iOS 팀에서는 @Eddy가 리드를 해주시고 우리 백엔드 팀에서는 @후가 분위기를 밝게 만들어줘서 매일매일 즐겁게 아침을 시작할 수 있었습니다. iOS 팀과의 첫 만남에서는 자기소개와 간단히 아이스 브레이킹을 한 후 회의 시간, 회의록 작성, 브랜치 관리, 커밋 메시지 컨벤션, Github 에서 제공하는 기능인 Projects, Issues, wiki 활용 방안 등 많은 이야기를 나눈 후 각 팀 별로 작업을 수행했습니다.
첫 날(4.4)
Git 레퍼지토리 관리라든가, iOS 팀에게 API 문서를 제공하는 일, AWS 배포를 통해 실제 서비스를 운영하는 일 등 처음해보는 일들이 너무 많아서 지금 당장 자신있게 할 수 있는 일들을 모두 탄탄하게 해놓고 나머지 부분들을 하나하나 해결해나가보자! 마인드로 프로젝트에 임했습니다. 가장 먼저 재빨리 기본적인 환경설정을 해가며 프로젝트 만들었습니다. 개발단계에서는 H2 인메모리 데이터베이스를 사용하여 테이블 구조 변경에도 큰 부담감이 없도록 했습니다. 중간중간 설계가 뒤바뀌거나 iOS 팀 분들의 요구사항이 추가되어도 큰 에너지 소비 없이 작업을 진행해 나갈 수 있었습니다. 그리고! lombok
을 적극 활용해보도록 후와 협의를 했습니다! 평소에 지저분해 보이는 코드를 별로 좋아하지 않았고, 간결한 코드를 좋아하는데 lombok 은 많은 코드를 자동으로 생성해주기 때문에 꼭 사용해보고 싶었습니다. 흔쾌히 후가 동의를 해주어 처음에는 꼭 필요한 어노테이션들(@Getter
, @AllArgsConstructor
만 사용했고 차츰차츰 @RequiredArgsConstructor
같은 어노테이션도 사용하여 스프링 기능과 밀접한 관련이 있는 어노테이션도 사용해볼 수 있었습니다. @AllArgsConstructor 어노테이션 덕분에 정적 팩토리 메서드를 작성하여 생성자를 대신하게 하였고 해당 방식으로 코드를 한결 더 깔끔하게 작성할 수 있었습니다. 후반부에 가서는 @Builder, @AllArgsConstructor(access = AccessLevel.PRIVATE) access 속성 값 등 리뷰어께서 lombok 관련한 조언들도 많이 해주시어 잘한 선택이라고 생각하게 되었습니다.
둘 째 날(4.5)
heroku
와 swagger-ui
를 사용해 IOS 팀이 확인할 수 있도록 API 문서를 제공했습니다! Controller 클래스를 설계하면서 문서화하기에는 아직 명확한 그림이 나오지 않아 껍데기 컨트롤러들만 만들어놓고 API 를 명세하였습니다. AWS 는 사용할 줄 모르지만 heroku는 이전 미션에서 사용해봤던터라 h2 데이터베이스와 더불어 유용하게 사용했습니다. 왜 개발단계에서 h2와 heroku가 자주 사용되는 지 알 수 있었습니다 🤗. 배운 것을 바로바로 써먹어서 그래도 나름?! 과정에 충실히 임했구나! 하는 느낌이 들었습니다.
iOS 분들은 해당 내용들을 보면서 기능을 구현할 수 있었고, 백엔드 팀인 후와 저는 요청 사항을 반영하거나 문서와 코드를 구체화하며 작업을 진행할 수 있었습니다.
셋 째 날(4.6)
공통수업 시간에 JK의 말씀대로 로그인 기능을 구현하지 않기로 한 날이었습니다. 이미 간단하게 작성해놓은 관련 클래스들이 있긴했지만, 단순하게 지우기보단 Controller, Repository 테스트를 작성해서 후와 코드 작성 스타일을 맞춰보고자 했습니다. 스프링 카페 미션 때와는 달리 json 으로 응답을 해야했기 때문에 사뭇 달랐습니다. 특히,
resultActions.andExpectAll(
....
content().encoding(StandardCharsets.UTF_8),
....
);
해당 부분을 검증하는데 많은 애를 썼습니다. 스프링 카페 미션 때에는 응답 시에 CharacterEncoding 을 설정하지 않았어도 자동으로 UTF-8 로 설정되었던 것 같은데, 그렇다고 모든 응답마다 각각 CharacterEncoding 을 반복적으로 설정하고 싶지는 않았습니다. 스프링 카페 때와 무엇이 달랐을까?! 계속 코드를 읽어보다가 이전 미션에서는 응답을 Json 이 아닌 html 파일이었다는 것을 깨닫게 되었습니다. 당장 html 파일을 살펴보았고 마침내 원인을 찾을 수 있었습니다.
<meta charset="utf-8">
바로 HTML 문서의 와 사이에 입력하는 특수 태그, 서버와 브라우저 간에 상호 교환되는 정보를 정의하는데 사용하는 html 의 meta 태그 때문이었습니다. 해당 태그에서 이미 charset 을 utf-8 로 설정해놓았기 떄문에 어플리케이션 단에서 CharacterEncoding 값을 설정할 필요가 없었던 것입니다. 현재는 응답이 html 이 아니므로 어플리케이션 단에서 charset 을 설정하도록 하되 모든 요청에 대해 공통적으로 처리할 수 있도록 HandlerInterceptor 를 구현하여 동작하도록 설정했습니다.
@Component
public class EncodingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
return true;
}
}
넷 째 날(4.7)
카드의 순서를 변경하고 이에 대한 레이아웃을 저장하는 방식에 대해 전날에 후와 이야기를 나눴었고, 해당 내용들을 iOS 팀 분들에게 전달하여 회의를 진행하게 되었습니다. 카드의 추가, 수정, 삭제, 이동 이벤트가 발생할 때마다 해당 카드, 그리고 순서에 영향을 받은 모든 카드의 위치의 변경사항을 즉각 데이터베이스에 반영하는 것이 아니라, 카드의 현재 위치인 position 칼럼을 제외한 추가, 수정, 삭제, 이동 이벤트에 관한 정보만을 테이블(Task, Log)에 저장하고 전체적인 레이아웃의 결과는 iOS 앱이 종료되었을 때 일괄적으로 저장할 수 있도록 기능을 구현하기로 협의를 했습니다. 소통의 과정에서 큰 어려움 없이 서로의 이야기를 나눌 수 있었고 무엇보다 어려운 일이 아니라며 흔쾌히 수용해주신 iOS 분들 덕분에 저희 또한 간단하게 기능을 구현할 수 있었습니다.
다섯 째 날(4.8)
일주일을 쉬지 않고 달려와서 그런지 쪼끔 풀렸습니다. 초반에 전반적으로 많은 것을 신경쓰다보니 지치기도 하고 제가 무언가를 하기보단 강의를 듣고 싶어져서 AWS 배포를 위해 호눅스의 녹화 강의에서 필요한 부분을 찾아 학습했습니다. 성공 케이스만 보여주는 것이 아닌 실패 케이스를 과정 속에서 계속적으로 보여주시고 해당 이유를 설명해주시면서 강의를 진행해주셔서 큰 어려움 없이 내용을 이해할 수 있었습니다. 바로 AWS 배포를 하진 않았고 아 이런 방식으로 배포를 하면 되겠구나! 만 파악하고 휴식 모드에 돌입했습니다 😴
여섯 째 날(4.11)
AWS 배포 후 자료를 정리하여 후에게 공유하고 싶었지만 주말 내내 아파서 A배포만 성공하고 자료를 정리하진 못했습니다 😭 드디어 heroku 가 아닌 AWS 로 iOS 팀들에게 API 문서와 데이터를 제공할 수 있게 되었습니다! 🤗 우리의 고마운 @민지노가 알려준 윈도우의 MobaXterm
을 사용하여 putty 보다 쉽게 서버를 다룰 수 있었습니다. 다만,
다음과 같이 세션이 자꾸 종료되어 iOS 팀 분들에게 서버가 죽었다고 말씀주셔서 계속 고민 중에 있었습니다. vi 로 ssh keep-alive 설정을 수정해보기도 하고 MobaXterm 자체의 설정을 바꿔보기도 했지만 알 수 없는 이유로 종료되는 세션을 보고 있자니 답답했습니다. 다행히! 우리의 후가 nohup
이란 명령어를 알려주었고 이를 통해 간단하게 해결할 수 있었습니다 😭 세션이 죽어도 어플리케이션이 동작할 수 있도록 할 수 있다니.. (이래서 후를 놓칠 수 없는데..)
일곱 째 날(4.12)
후는 본격적으로 카드의 핵심 기능들을 구현해나가기 시작했고, 저는 활동기록 관리 기능을 어떻게 구현하면 좋을까 생각해보는 시간을 가졌습니다. 물론 AOP
를 사용하여 기능을 분리하는 방식으로 구현하기로 했지만, Card의 동작과 관련이 있는 기능이이었기 때문에 후의 개발 단계 그리고, 후의 구현 방식과도 관련이 있었기 때문에 양쪽을 모두 살펴보며 코드를 작성할 때 막힘 없이 진행하고 싶어 꾸준히 고민하고 있었습니다. 하지만 생각을 계속 하다보니 활동기록은 완전 별도의 동작이기 때문에 분리할 수 있었던 기능이고 이에 따라 제가 신경써야할 부분은 iOS 단에서 보내주는 요청 파라미터 정보와 AOP 기능의 사용 방법이었습니다. 구현 방향이 명확해졌기 때문에 필요한 문법들을 작성해보고 실행해보면서 동작을 확인해봤습니다. 그렇게 계속 학습해보다가 마침내 간단하게 AOP 를 사용하여 활동로그를 구현해볼 수 있었습니다!
execution( com.hooria.todo.service.CardService..(..))
- CardService 내의 모든 메서드에 대해서 활동기록을 남기도록 pointCut 을 설정하고
!@annotation(com.hooria.todo.aop.ExcludeLogging)
- 카드 추가, 수정, 삭제, 이동 기능 메서드에 대해서만 활동기록을 남기도록 커스텀 어노테이션을 사용
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcludeLogging {
}
여덟 째 날(4.13)
배포 설정 정보를 어떻게 숨길 수 있을까 생각해보다가 단순하게 .gitignore 파일로 application-prod.properties 파일을 숨기고 배보된 jar 파일을 -Dspring.profiles.active=prod 옵션을 주어 실행했을 뿐인데 리뷰어님께 👍 을 받아서 좋았습니다 😁 스프링 카페 미션 때에는 배포 설정 정보를 숨기기는 커녕 개발, 배포 설정 파일을 분리할 생각조차 못했었는데 정말 많이 발전한 것 같습니다.
아홉 째 날(4.14)
프로젝트가 막바지에 이르렀고 더이상 무언가 기능을 추가하기보단 다른 구현 때문에 미뤄두었던 자잘한 기능들을 추가했습니다. 중요하지만 간과하기 쉬운 예외처리를 위해 ErrorCode, ErrorResponse 클래스를 정의하고 ExceptionHandler 어노테이션을 사용하여 도메인마다 특정 예외 처리를 담당하는 메서드를 정의했습니다.
마지막 날(4.15)
간단한 데모(호눅스의 클래스 별 피드백 시간과 겹쳐 😭 짧게 마무리했던..)를 마치고 @에디
, @후
, @산토리
, @필
, @아더
, @루이
, @싱하
와 왕십리역에서 조인하여 간단하게 뒤풀이 시간을 가졌습니다. 전 페어인 @아더를 처음 봤는데, 역시나 어색하지 않고 금새 장난치는 사이가 될 수 있었습니다. @아더와 @후의 티격태격하는 캐미를 보니 두 사람이 팀 프로젝트를 하면 정말~ 보기 좋을 거 같다는 생각을 하게 되었습니다 😏
마무리
특별히 무언가를 더 많이 알려주고, 제가 막 그렇게 잘한 건 없는데 옆에서 마냥 잘한다잘한다 해주는 후가 있어서 힘든 줄도 모르고 프로젝트를 진행할 수 있었습니다. 제가 줌이나 디스코드 연결 상태가 좋지 않아 음성이 끊기기 때문에 슬랙 전화로 대화를 자주했음에도 불평 한 번 안한 후가 너무 고마웠습니다. 제가 많은 것을 알아서 후한테 더 많은 것을 알려주고 공유해줬으면 좋았을텐데 항상 싱글벙글한 후의 목소리를 듣고 있자니 미안한 마음이 많이 들었습니다. 저 또한 후한테서 많은 것을 배웠는데 후도 그걸 알아줬으면 좋겠습니다 😄
프로젝트 진행에 있어서의 아쉬움도 있었습니다. 문서화 작업에 좀 더 많은 시간을 들였어야하지 않았나 하는 생각이 떠나질 않았습니다.
위와 같이 리뷰어께서도 3번 째 pr 에서 해당 내용을 리뷰해주셨습니다. 공유 문서로 후와 작성해가며 소통해도 큰 무리가 없었기에 문서화 작업에 소홀히 했습니다. 해당 프로젝트의 참여자가 아닌 분들의 이해를 돕기 위해 문서화 작업은 필수였는데, 기능 구현이나 테스트 코드 작성에 몰두하여 시간을 투자하지 않았습니다. 다음 팀인 테리와는 꼭! 문서화 작업을 충실히 하려고 합니다.
원래 저는 코드를 작성하는 것에 흥미를 더 가졌었는데, 팀 프로젝트를 통해 팀원들과 의견을 공유하면서 맞춰가고 서로의 생각들을 이해하는 과정 자체가 더 즐거웠습니다. 리뷰어 분께서 학습거리를 이것저것 던져주셨는데 얼른 다시 리뷰 내용들을 정독하고 머릿 속으로 먼저 정리를 하고 글로도 정리를 해봐야겠습니다. 자꾸 해야할 일들이 쌓여가지만 머릿 속에도 쌓여가고 있기 때문에 불안함보다는 뿌듯함이 더 많이 느껴지는 요즘입니다 😄
Author And Source
이 문제에 관하여([CodeSquad] TODO-LIST 팀 프로젝트 후기(4.4~4.15)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@naneun/CodeSquad-TODO-LIST-팀-프로젝트-후기4.44.15저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)