들어가며

안녕하세요. 저는 우아한테크캠프를 통해 우아한형제들에 합류한 배민서버개발팀의 김민지입니다.
이 글을 통해 저희 팀에서 진행하고 있는 신입 교육의 일환인 Show me the code라는 파일럿 프로젝트를 진행한 경험을 공유하고자 합니다.(다인님이 1기이고 저는 2주 늦게 합류한 2기입니다ㅋㅋ)
기능 구현이나 기술에 대한 자세한 설명 보다는 느낀점과 생각 위주로 작성하려고 합니다. 그럼 스타뜨!

간단 주문 시스템

프로젝트의 주제는 결제 API와 연동해서 상품을 주문을 할 수 있는 간단한 서비스를 만드는 것입니다. 프로젝트의 목표는 다음과 같습니다.

  • 상품 : 상품 목록에서 상품을 선택하고 상품 상세에서 옵션을 선택할 수 있어야 한다. 한 개 이상의 카테고리와 옵션을 갖는다.
  • 주문 : 결제 시스템과 연동하여 주문을 할 수 있어야 하며, 완료된 주문을 취소할 수 있어야 하고, 주문한 내역을 볼 수 있어야 한다.
  • 회원 : 회원은 구분만 할 수 있으면 된다.
  • 예쁜 화면: 100% 선택 사항

엄청난 4주간의 일정이 픽스되어 있었습니다.(실제론 뒤에 리팩토링을 하는 hidden 주차가 있습니다)

일정

그리고 여기 저에게 고독을 안겨준 규칙이 하나 있습니다.

규칙

물어보지 말라뇨???

한창 호기심 많을 2주차 신입에게 물어보지 말라는 규칙이라니!!!! 저는 테크캠프에서 대부분의 시간을 페어프로그래밍을 진행을 했습니다. 그래서 질문하고 토론하는 훈련(?)에 익숙해진 저에게 물어보지마시오 규칙이 처음에는 이해가 되지 않았습니다. 이런 규칙이 있는 이유는 혼자 개발부터 배포까지 해보는 경험을 통해 많이 배울 수 있다는 것이었습니다. 혼자서 개발하는 일은 없을텐데… 라는 약간의 의심을 갖고 개발을 시작했습니다.

개발에 들어가기에 앞서

먼저 주어진 요구사항은 다음과 같습니다.

  • 요구 사항
    • 객체지향적인 코드
    • 단위 테스트
    • JIRA를 통한 이슈 관리
    • GIT 버전 관리
    • API 문서
    • (선택사항) 통합 테스트
    • (선택사항) 주문 관리 ADMIN

처음에 한 일은 To-do 리스트를 작성하는 것이었습니다 . 그 리스트를 바탕으로 대략적인 2주간의 일정을 계획하였습니다. 그 후에 한 일은 ERD를 뽑는 것이었습니다. 저는 경험이 적어서 이 부분을 설계하는 것이 제일 어려웠습니다. 그리고 나름 치열하게 고민한 끝에 다음과 같이 요상한 ERD가 나왔습니다. 이 프로젝트의 문제는 여기서 시작 된 것 같습니다ㅠㅠ

old-erd

개발을 시작했으나

ERD를 완성하고 찝찝한 마음을 갖고 드디어 개발에 들어갔습니다. Spring Initializr를 이용해 프로젝트를 생성하고 가장 간단하게 상품 화면을 보여주는 것부터 시작했습니다. 선택사항이었지만 통합테스트를 만들고 배웠던 대로 TDD를 이용해서 개발을 진행했습니다.(테크캠프 짱!!!)

다음 스텝으로 연동할 결제 API의 docs와 위키를 보면서 주문하기를 개발했습니다. 외부 API를 호출해 본적이 없어서 이 부분을 개발 할 때 가장 오랜 시간이 걸리고 고민이 많았습니다. 그래도 잘 작성된 문서들이 도움이 되서 결국 결제 API와 연동을 해서 주문하기를 성공했습니다. 이 때 잘 작성된 문서의 중요성을 또 다시 느낄 수 있었습니다.

card-complete-order

[정겨운 UI]

이 때까지만 해도 선택사항도 전부 다 하고 예쁜 화면도 꾸밀 생각이었습니다. 그런데 초반에 화면을 어떻게 구성해야 할지 생각을 별로 안하고 개발을 한 탓에 API 개발이 완료 후에 화면의 요청에 따라 Controller 부분이 바뀌게 되고 그에 따라 테스트들도 변경되는 바람에 제 시간에 필수 요구사항을 겨우겨우 완성하게 되었습니다.(진짜 최소한의 화면에서 최소한의 기능만…)

공포의 코드리뷰

드디어 대망의 코드리뷰 날. 아주 많은 피드백을 받았던 걸로 기억합니다… ERD가 불명확, 컨트롤러에서 너무 많은 일을 하고 있음, @Transactional의 범위에 결제 API와 연동이 되어 있음, 예외처리 부족, 불필요한 코드 등등… 제가 생각했던 부분도 있었고 전혀 생각지도 못한 부분도 있었습니다.

code-review

[공포의 현장]

코드리뷰를 마친 직후 심정은

다 나가주세요. 혼자 있고 싶습니다…

너무 못한 거 같아 부끄럽고 자괴감이 들었습니다. 하지만 시간이 지나 생각해보니 저의 부족한 점을 그대로 보여줬을 때 못했다고 질책을 하는 것이 아닌 부족한 점을 채워 나갈 수 있도록 조언하고 격려해주는 팀원들이 있어서 정말 좋았습니다.

그리고 이 시간을 통해 파일럿 프로젝트의 진가를 알게 되었습니다. 혼자 고독한 시간을 보내면서 들었던 생각과 고민을 공유할 수 있고 그에 대한 다른 사람들의 의견을 통해 생각지도 않았던 문제를 발견하고 해결 방법을 얻을 수 있었습니다. 이를 통해 프로젝트의 전체적인 설계와 객체지향적인 코드에 대한 감을 잡을 수 있었습니다.(정말 잡은 걸까요 허허) 또한 이렇게 시간을 내서 참여해주신 분들의 관심과 열정을 통해 동기부여가 되기도 했습니다.

개발을 했으면 뭘 하나? 배포!

배포의 요구사항과 스펙은 아래와 같습니다.

  • 요구 사항
    • 무중단 배포
    • 안정적인 배포
    • (선택사항) 배포 알람
  • 스펙
    • AWS Beanstalk
    • AWS RDS
    • Jenkins

배포는 테크캠프에서 1번 다 같이 해봤는데 제가 모르고 넘어갔던 부분이 많았습니다. 그래서 시작 전에 잘 할 수 있을까 걱정이 많았습니다(이 고비가 지나가면 다음 고비가 온다는 말이 생각나는 군요…) 검색을 통해 jojoldu 블로그라는 반칙 치트키를 찾을 수 있었고 이외에 여러 자료들을 참고해 다음과 같은 순서로 진행했습니다.

  • EC2 생성해서 Jenkins 설치
  • Jenkins와 Github 연동
  • Jar 파일 업로드용 S3 생성
  • Jenkins와 S3, Beanstalk 연동
  • AWS RDS 생성
  • Spring Profile을 적용해 local과 development의 배포 환경을 다르게 설정
  • 무중단 배포를 위해 Beanstalk의 환경을 하나 더 생성하고 swap url 적용

자세한 설명은 여백이 부족하여 생략…하고 시스템구조도로 대체하겠습니다’v’

system-structure

배포를 하면서 코드의 수정이 필요한 부분이 있었습니다. 개발할 때 먼저 이 부분을 고려했다면 더 좋았을 것이라는 생각과 함께 인프라를 알고 개발하는 것이 중요하다는 것도 느꼈습니다.

배포가 끝이 아니다! 리팩토링~

배포까지 완료된 후에는 코드 리뷰에서 나온 피드백 중 가장 큰 문제였던 ERD를 변경했습니다. 프로젝트 멘토님이 만약 상품의 이름이나 가격이 바뀌면 변경 전 주문들의 상품 데이터도 변경되기 때문에 상품에 대한 스냅샷을 주문에서 갖고 있도록 해보라는 조언을 해주었습니다.

new-erd

이를 반영해서 product와 order의 관계를 제거 하고 orderProduct를 만들도록 수정했습니다. 아직 코드 리뷰의 피드백을 반영 중에 있지만 의존 관계가 줄어들어 코드가 훨씬 깔끔해졌습니다.

고독한 개발자는 없다!

제가 이 프로젝트를 하면서 가장 많이 배웠다고 생각한 때는 코드리뷰와 코드리뷰 후 1기인 다인님과 설계 및 코드에 대한 의견을 나눌 때입니다. 제가 고민하고 궁금했던 내용들을 질문하고 토론하고 피드백 받는 시간을 통해 몰랐던 문제들을 알게 되고 더 나은 방향으로 바꿀 수 있는 여러 힌트를 얻는 시간이었습니다. 그러나 이는 혼자 고민했던 시간이 없었다면 느낄 수 없었다고 생각합니다.(이래서 혼자 해보라고 하셨군요!) 이 프로젝트를 통해 앞으로 스스로에게 질문을 던지며 고민하고 그 결과를 공유하고 토론하며 성장하는 핵인싸 개발자가 되고자 합니다. 두서없는 글이지만 읽어주셔서 감사합니다.