[레벨2] 장바구니 주문 미션 (협업)
- 1단계 저장소: https://github.com/yoondgu/jwp-shopping-order/tree/step1
- 2단계 저장소: https://github.com/yoondgu/jwp-shopping-order/tree/step2
- 2단계 코드리뷰 진행 PR: https://github.com/woowacourse/jwp-shopping-order/pull/47
[2단계 - 주문 기능 구현] 도이(유도영) 미션 제출합니다. by yoondgu · Pull Request #47 · woowacourse/jwp-sho
안녕하세요 라빈! 🍨 리뷰이 도이입니다!! 마지막 미션을 함께 하게 되어 영광이에요~ 요청이 많이 늦었지만.. 같이 많이 대화하며 배워가고 싶습니다 😆 잘 부탁드립니다!! ㅎㅎ 백엔드, 프
github.com
기능 요구사항
실제로 동작하는 서비스를 만들기 위한 클라이언트, 서버 간의 간단한 협업을 경험하는 미션
0 ~ 1단계 : 기본 코드 준비, 클라이언트 - 서버 연동
- 제공된 미션 뼈대코드 파악
- 상품, 장바구니 기능이 구현된 코드 배포
- 상시 배포를 위한 배포 스크립트 작성
- 클라이언트와 API 연동하며 발생하는 보안 이슈에 대응
2단계 : 주문 기능 구현
- 팀 내 세부 기획, API 명세 결정
- 결정된 기획 및 API 명세에 맞춰 각자 코드 구현
- 장바구니에 담은 상품 주문
- 상품 주문 시 현실 세계의 쇼핑 서비스가 제공하는 재화 관련 요소를 최소 1가지 이상 추가
- 사용자 별로 주문 목록을 확인
- 특정 주문의 상세 정보를 확인
작성한 요구사항 목록, API 명세, 코드리뷰 피드백 및 리팩터링 목록은 저장소의 README.md(이곳)에서 확인할 수 있다.
이번 미션의 경우 백엔드는 2단계만 코드리뷰를 진행했다.
전체 회고
빠른 상황 파악 및 문제 해결 능력을 기르자
배포 스크립트 작성을 처음 해봤다.
페어들이 구글링, chatGPT를 활용해 빠르게 스크립트를 작성하는 것을 보고 인상 깊었다. 덕분에 도움을 많이 받았다.
대신 나는 이 스크립트가 왜 이렇게 짜여져있는지를 보고 고민하는 데 시간을 많이 썼다.
이런 성향이 도움이 될 때도 있지만, 빠르게 문제 해결을 할 줄 아는 능력도 길러야 할 필요를 느꼈다.
그리고 나도 이제는 CLI에 익숙해질 때가 된 것 같다!!! 이번 기회에 vim 단축키 연습도 많이 해보았다.
구현 내용이 복잡할 수록 작은 것부터 차근차근 하자
우리 팀은 중간에 요구사항이 추가되는 경험을 하고 싶음 + 일정 관리를 위해 아래와 같은 순서로 진행했다.
[기본 기능 팀 회의(API 명세 작성) - 기본 기능 구현 - 추가 기능 팀 회의(API 명세 변경 및 작성) - 추가 기능 구현]
그러다 보니 추가 기능 구현에서 여러 부분에 복잡한 변경 사항이 있었다.
이를 빠르게, 한번에 구현하다보니 그 어느때보다 실수가 잦았다.
늦지 않게 구현을 완료해 프론트엔드 분들이 사용 가능하게 하고, 개인적으로는 리뷰 요청을 보내고 여러 번 피드백을 받고 싶은 마음 때문이었다.
평소 초기 구현을 할 때처럼 기능 목록을 작게 나누어 차근 차근 해야겠다는 교훈을 얻었다.
프론트엔드와의 첫 협업
백엔드 - 프론트엔드 협업을 처음으로 경험해보았다!
다들 잘 맞춰주시기도 하고 의견도 잘 맞아서 큰 탈 없이 미션을 잘 마무리할 수 있었다.
다만 실제로 "클라이언트"가 존재하는 환경에서 개발해본 것이 처음이라 서툴기도 했고, 그만큼 재밌기도 했다.
서버에 배포된 이상 프론트 측에서 API를 사용하고 있는데, 처음에는 이를 간과하고 뭔갈 수정하고 말없이 다시 배포하기도 했다.
이후에는 상황을 바로 바로 공유하면서 잘 진행할 수 있었던 것 같다.
다만, 매번 프론트 분들께 현재 배포 버전이 잘 작동되는지 대신 확인해달라고 하기 보다는 내가 먼저 확인해보고, 배포 했음을 알리고 싶었다. (테스트 컨텍스트를 띄워서는 통과하지만, 실제 배포 환경에서는 안될 수도 있겠다 싶어서)
그래서 POSTMAN으로 미리 먼저 확인을 해보곤 했는데, 이런 테스트를 더 편리하게 빨리 하는 방법을 몰라서 조금 비효율적으로 작업했던 게 아쉽다.
그런데 나중에 알고보니 POSTMAN에서도 자동화를 할 수 있다고 프론트 팀원 분께서 알려주셨다!! 담엔 이를 적용하고 싶다.
null을 어떻게 다룰까?
그 외에는 백엔드 팀원 간에 null을 사용하는 법에 대해 서로 의견이 다른 부분이 있었다.
우리는 쿠폰 정책을 추가로 구현했는데,
쿠폰을 사용하지 않은 주문 정보에 대해서 쿠폰 정보를 표현할 때 아래 두 가지 선택지가 있었다.
"null을 보내기 vs 쿠폰을 사용하지 않는 정보를 표현하는 쿠폰 객체(id는 0으로 관리)를 보내기"
당시에는 이미 null로 보내기로 협의된 상태에서 추가 논의가 시작되었다.
난 이미 해당 협의 대로 구현을 마친 상태였는데, Optional로 감싸서 null인 경우와 아닌 경우의 분기처리를 적절히 해보니 크게 문제 없다는 생각이었다. 물론 Optional로 감쌌다고 해도 null이 계속 전파되는 게 찜찜하지만..
그리고 쿠폰을 사용하지 않음을 표현하는 id가 별도로 있는 게 어색하다고 생각했다.
쿠폰 객체가 null이면 쿠폰을 사용하지 않는다는 의미가 더 명확하지 않나? 라는 생각 때문이었다.
늘 null에 대해서는 이런 딜레마를 느낀다. null이 "없음"을 의미하지 않나? vs 그런데 null이 있으면 지뢰처럼 찜찜하다 ..
하지만 과연 개발자가 완벽하게 NPE safe한 코드를 작성한다고 보장할 수 있을까?
또, null이 "없음"을 의미하는 경우와, 코드 실수로 null을 받는 경우를 구분할 수 없지 않을까?
그런 측면에서는 후자가 더 좋은 방법일 수도 있다는 생각도 든다.
null을 피하는 게 아니라 null 대신 다른 것을 사용하는 null 객체 패턴으로 말이다.
(마침 향로님 블로그에 관련 글이 올라와서 재미있게 읽었다!! 3. 좋은 함수 만들기 - Null 을 다루는 방법)
미션 로그
- ATDD
- vim 사용법
- SOP, CORS 정의와 대응 방법
- Nginx, certbot 사용하여 SSL 인증서 적용하기 (HTTP -> HTTPS로 변경)
- API 문서화 (Swagger)
- AWS Cloud 네트워크 구성 이해, EC2 사용하기
- DB를 외부 서버로 분리하고 연동하기
- HTTP 상태코드 적절하게 사용하기
- Null값의 허용/비허용에 대해 Primitive/Wrapper 타입을 잘 구분해서 지정하기
주요 기술 부채
- Nginx
- 쉘 스크립트 문법
- API 문서화 RestDocs로 해보기
- PostMan 자동화
- Spring Boot External properties / 서브모듈 로 보안 정보(DB 설정 등) git 관리 코드와 분리하기
- CI / CD