오늘도 개발
[1차 프로젝트 록차] 프로젝트 최종 회고 본문
1. 프로젝트 개요
우리 팀은 1차 프로젝트로 오설록 쇼핑몰을 클론코딩하여 '록차'라는 쇼핑몰을 만들었다.
기획, 디자인만 오설록을 참고하고 기능은 모두 직접 구현하였다.
클론코딩 사이트로 오설록을 선정한 이유
오설록은 멤버십으로 운영되는 사이트이므로 회원가입, 로그인 등 인증/인가와 관련된 기능(bcrypt, jwt)을 구현해볼 수 있다.
쇼핑몰이므로 장바구니, 상품 구매, 주문 관리 등 기본적인 주문 관련 기능을 구현해볼 수도 있다.
무엇보다도 오설록은 카테고리가 상세하고 상품 타입도 다양하다.
그래서 일대다, 다대다 테이블 등 관계형 데이터베이스를 위한 모델링을 연습하기에 적절해보였다.
또한 제품군이 다양하기 때문에 필터링 기능을 구현하며 django 쿼리에 익숙해질 수 있으리라 기대했다.
개발 인원
프론트엔드 4명, 백엔드 3명(나 포함)
개발 기간
2022.7.18 ~ 7.29(2주)
내 역할
DB 모델링, API 구현(카테고리, 상품상세, 상품목록), AWS 배포
과정
[1차 프로젝트 록차] 상품 목록 GET api 제작기 1 - RESTful한 엔드포인트 만들기
[1차 프로젝트 록차] 상품 목록 GET api 제작기 2 - 어떻게 필터링을 구현할까
[1차 프로젝트 록차] 상품 목록 GET api 제작기 3 - Django Q 오브젝트 사용하기
[1차 프로젝트 록차] 상품 목록 GET api 제작기 4 - django paginator로 페이지네이션 구현하기
[1차 프로젝트 록차] Postman으로 batch request 보내기
[1차 프로젝트 록차] 상품 목록 GET api 제작기 5 - 리팩토링
기술 스택
개발 관련 : Python, Django, MySQL, Postman
협업 관련 : Trello, Notion, Slack, Git & Github
Github repository
https://github.com/eungang3/35-1st-LocTea-backend.git
배포된 결과물
http://1st-loctea.s3-website.ap-northeast-2.amazonaws.com/
시연 영상


DB 모델링
https://dbdiagram.io/d/62d4f8bc0d66c74655f3611e

API 명세서
2. 프로젝트에서 내가 맡은 역할
1) 상품 목록 API 제작
구현 사항
- 엔드포인트 /products/list로 요청받음
- 요청 성공한 경우 : 페이지 정보, 상품 목록과 코드 200 반환
- 요청 실패한 경우 : 존재하지 않는 카테고리나 페이지 요청 시 404 에러 반환
- 카테고리 필터, 티 타입별 필터, sorting 구현
- 페이지네이션 구현
배운 점
- 쿼리 파라미터를 이용하여 엔드포인트를 만드는 법에 대해 알게됨
- RESTful api의 개념을 익히고 코드에 적용해봄
- 처음에는 엔드포인트를 'products/1차 카테고리 아이디/2차 카테고리 아이디'로 작성했다.
- 하지만 products/1/2 같은 URI로는 리소스를 설명할 수 없었다.
- 전체 상품 중 카테고리가 oo번인 상품을 필터링해서 보여준다고 생각하니 더 가독성 있는 엔드포인트를 작성할 수 있었다.
- Q 오브젝트에 대해 공부하고 사용해봄
- 페이지네이션의 원리를 이해하고 Paginator 모듈로 구현
- 복잡해보이는 필터링과 페이지네이션도 글로 정리해보니 하나씩 구현할 수 있었음
- 어디서부터 시작해야 할 지 모르겠고 막막할 때는 글로 먼저 정리해보는 습관을 들이면 좋을 것 같다.
2) 상품 상세 API 제작
구현 사항
- 엔드포인트 /products/product_id로 요청받음
- 요청 성공한 경우 : 상품 상세 정보 응답
- 요청 실패한 경우 1 : 상품 아이디에 해당하는 상품이 없는 경우 401 에러로 응답
- 요청 실패한 경우 2 : 카테고리가 존재하지 않는 경우 401 에러로 응답
배운 점
- 문서화의 중요성을 느낌
- 처음에는 급한 마음에 API 명세서를 작성하지 않고 구두로 프론트와 커뮤니케이션을 했다.
- 작업을 진행하다보니 키값이 자꾸 맞지 않아 통신에 어려움이 생겼고, API 명세서를 만들었다.
- 명세서를 작성한 후 작업하니 프론트와 커뮤니케이션이 더 수월해졌고, 스스로도 어떤 기능을 만들어야 하는지 명확하게 정리가 되어 좋았다.
- 패스 파라미터와 쿼리 파라미터의 차이점을 알게됨.
- 패스 파라미터는 단순히 특정 아이디의 상품을 가져올 때 쓴다.
- 쿼리 파라미터는 filtering이나 ordering에 더 적절하다.
- 해당 api는 상품 정보를 가져오기 때문에 패스 파라미터를 사용했다.
3) 카테고리 API 제작
구현 사항
- 엔드포인트 /categories로 요청받음
- 요청 성공한 경우 1 : 모든 1차 카테고리명과 id, 2차 카테고리명과 id를 담은 딕셔너리와 코드 200을 반환.
- 요청 성공한 경우 2 : 아무 카테고리도 없는 경우 빈 리스트와 코드 200을 반환.
배운 점
- 위계를 갖는 데이터는 어떤 구조로 정리해서 보내주어야 프론트에서 사용하기 편할지 고민해봄.
- 처음에는 카테고리명만 보내주었는데 프론트쪽에서 url을 구성하려면 카테고리 아이디도 필요했다.
- '카테고리 아이디 : 카테고리명'으로 된 키값을 보내주는 경우 가독성이 가장 높고 프론트에서 사용하기도 편리했다.
- 리스트 컴프리헨션을 사용했을 때 코드 가독성이 좋아짐을 체감함.
3. 프로젝트 회고
Liked
1) 모든 팀원이 목표한 작업을 완료함
모든 팀원이 목표한 작업을 완료한 것이 가장 뿌듯하다.
목표한 작업을 완료했다는 것은 일정 관리에 성공했다는 뜻이고,
일정 관리에 성공했다는 것은 협업을 잘 했다는 뜻이기 때문이다.
개발자의 중요한 덕목 중 하나는 일정 관리라고 생각한다.
디자이너로 IT 회사에서 일할 때도 느꼈지만,
프로덕트는 혼자 만드는 것이 아니며 내 일정을 잘 관리하지 못하면 전체 팀원에게 지장이 간다.
일정을 잘 관리한다는 것은 단순히 맡은 일은 무슨 일이 있어도 완수한다는 뜻이 아니다.
일정에 맞추지 못할 것 같을 때 팀원들과 이야기를 나누고 일정을 조율하거나 도움을 받는 것까지가 일정관리이다.
그러니까 모든 사람들이 일정에 맞춰 할 일을 다 했다는 것은 서로서로 잘 도왔다는 뜻이기도 하다.
내 담당은 상품 관련 api였지만, 다른 부분을 담당하신 분이 버그로 괴로워하고 있으면
내 할 일은 잠시 멈추고 테스트 브랜치를 파서 같이 코드를 살펴보고 버그를 찾아보았다.
그러느라 내가 3시에 시작하려고 한 일을 5시에 시작하는 경우도 생겼지만
신기하게도 내 작업이 밀린 적은 없다.
내 코드가 잘 안풀릴 때는 다른 분들도 자기 일처럼 같이 고민해주었기 때문이다.
이렇게 다같이 고민을 공유하고 해결하는 분위기였기 때문에 모든 팀원이 일정에 맞춰 작업을 완료할 수 있었던 것 같다.
2) 프로젝트가 안 풀릴때도 웃는 얼굴로 서로를 대한 것
7명 모두 처음 해보는 개발 프로젝트였기 때문에 예상치도 못한 어려움은 자꾸만 생겼다.
잘하고 싶은 마음은 큰데 잘 안되면 짜증나는 것이 당연하고, 팀원 모두 한 번 이상은 일이 안풀려서 힘들어했다.
하지만 아무리 짜증나고 힘든 순간에도 서로가 서로를 최선의 태도로 대했다.
나는 프로젝트 초반에 모델을 django 코드로 바꾸고 마이그레이션 하는 작업을 담당했는데
혼자 할 때는 잘 되던 것이 되지를 않아서 세 번은 갈아엎어야 했다.
내가 세팅을 완료해야 다른 백엔드 팀원들이 프로젝트를 시작할 수 있는데
나 때문에 두 사람이 프로젝트를 시작조차 못하는 것 같아 식은땀이 났다.
하지만 팀원들이 짜증 한 번 안내고 같이 문제를 찾아줘서 마음이 편해졌고
마음이 편해지니까 긴장이 풀렸는지 안보이던 문제가 더 잘 보였다.
원래도 팀 프로젝트의 성패는 팀 분위기에 달렸다고 생각했는데
이 때 더더욱 좋은 분위기의 중요성을 느꼈고 나도 다른 팀원들을 이렇게 대해야겠다고 다짐하게 되었다.
Lacked
1) 1차 스프린트 - 문서화를 하지 못한 점
팀원들끼리 커뮤니케이션 할 때 주로 말로 소통하다보니 글로 하는 소통에 소홀했다.
특히 1차 스프린트 때 문서화를 잘 하지 않은 점이 아쉽다.
문서화를 하지 않으면 업무 효율이 떨어진다.
예를 들어 나는 1차 스프린트 때 상품 키값을 상품 화면을 만드는 팀원하고만 맞추고 작업을 진행했다.
다른 팀원도 상품 키값이 필요할 것이라는 생각을 못 했기 때문이다.
하지만 프로젝트가 진행되다 보니 장바구니 화면을 만드는 팀원도 상품 키값이 필요해졌다.
카테고리 화면을 만드는 팀원도 상품 키값이 필요해졌다.
정해진 문서가 없었기 때문에 나는 했던 말을 몇 번이나 반복해야 했다.
이건 2주짜리 작은 프로젝트이기 때문에 조금 불편한 정도에서 그칠 수 있다.
하지만 만약 여기가 실제 회사였고 이것이 배포 후 유지보수까지 해야하는 큰 프로젝트였다면
문서가 없어 발생하는 커뮤니케이션 비용이 어마어마했을 것이다.
내가 갑자기 부서이동이라도 한다면 내 후임은 물론 팀원 전체가 괴로워질 것이다.
2) 2차 스프린트 - 문서를 활용하지 못한 점
문서화의 중요성을 깨달았기 때문에 2차 스프린트 때는 api 명세서를 도입했다.
백엔드 쪽에서는 api를 만들면서 바로바로 명세서를 작성하고
프론트 작업자들은 명세서만 보고 작업하는 것이 목표였다.
결론적으로 명세서가 있어도 활용을 못 했다.
백엔드 작업자들은 마음이 급해서 일단 api부터 만들고 프론트와 통신까지 마친 후에야 명세서를 작성했다.
프론트 작업자들은 마음이 급해서 작성된 api 명세서가 있어도 확인하지 않고 백엔드 개발자를 호출했다.
api 명세서를 제대로 활용하지 못한 이유는 모두의 마음이 급했기 때문인 것 같다.
작업에 몰두하다 보면 빨리 결과를 내고 싶은 마음에 당장 빨라보이는 길을 택하게 된다.
문서를 작성하고 확인하는 시간에 지금 당장 가서 물어보는 게 낫게 느껴진다.
하지만 어떤 프로젝트든 결과만큼 과정이 중요하다고 생각한다.
무엇보다도 어떻게 하면 더 잘 협업할 수 있을 지 고민하며 작업했을 때 더 좋은 결과가 나올 수 밖에 없다.
다음 프로젝트에서는 이런 부분에 대해 구성원들과 이야기를 나누며 진행해보고 싶다.
결과만큼 과정이 중요하다는 합의가 된 이후에야 api 명세서를 제대로 활용할 수 있을 것 같다.
Learned
1) 코드 작성이 막막할 때는 일단 글로 정리해보면 좋다.
상품 목록 api를 만들 때 한 엔드포인트로 모든 필터링을 구현해야 한다는 사실이 너무 막막했다.
1차 카테고리만 클릭한 경우, 2차 카테고리만 클릭한 경우, 1차 필터와 2차 필터를 동시에 클릭한 경우,
아무 필터도 클릭하지 않은 경우 등 가능한 경우의 수가 너무 많은데 어떻게 정리해서 코드로 나타낼 수 있을까?
아무것도 정리되지 않은 상태에서 코드를 칠 수 없어 글로 내 생각을 먼저 정리해보았다.
일단 가장 기본이 되는 엔드포인트를 적어보았다.
필터는 쿼리 파라미터로 받을 예정이었으므로 쿼리 파라미터가 추가된 엔드포인트도 모두 써보았다.
모든 엔드포인트를 적고 보니 어느 경우에 어떤 디폴트 값을 주어야 하는지 정해줄 수 있었다.
(정리 결과 > 록차 API 명세서 - 상품 목록 api)
한 두시간 정도 글로 내 코드가 해야 할 일을 정리해보니 내가 무엇을 해야 할 지 알 수 있었다.
나는 동적으로 쿼리를 만드는 방법과 장고에서 페이지네이션을 구현하는 방법을 알아야 했다.
여기부터는 쉬웠다. 검색을 해서 Q객체와 페이지네이터 객체에 대해 알아냈고 어떻게 쓰면 되는지 공부했다.
그 다음엔 내가 정리한 글을 코드로 바꾸기만 하면 되었다.
그냥 이전 기수 블로그를 찾아 남의 코드를 보고 필터링을 구현할 수도 있었을 것이다.
하지만 충분히 생각하고 글로 정리해보았더니 얼마든지 내 힘으로 문제를 해결할 수 있었다.
내 힘으로 풀었을 때 좋은 점은 코드를 완전히 이해하고 작성할 수 있다는 점 같다.
코드를 이해하면서 썼기 때문에 코드가 작동 했을 때도 작동하지 않았을 때도 왜 그런지 이유를 쉽게 파악할 수 있었다.
앞으로도 개발을 하다 막히면
먼저 생각하고 -> 글로 생각을 정리한 후 -> 코드를 작성하는 방법을 사용해보아야겠다.
기록)
상품 목록 GET api 제작기 2 - 어떻게 필터링을 구현할까
상품 목록 GET api 제작기 3 - Django Q 오브젝트 사용하기
상품 목록 GET api 제작기 4 - Django Paginator로 페이지네이션 구현하기
2) api는 화면이 아니라 기능을 기준으로 설계해야 한다.
메인 페이지에서도, 상품 페이지에서도 상품 목록을 보내주는 api가 필요했다.
처음에는 화면 위주로 생각해서 api를 두 개 만들었는데
멘토님께서 기능 위주로 생각하면 api를 합칠 수 있을 것이라고 하셨다.
생각해보니 메인 페이지의 '여름 특가 상품'에 들어가는 api는
기능적으로 상품 페이지의 들어가는 api와 다를 것이 없었다.
상품 페이지에 들어가는 api는 카테고리 정보를 쿼리 파라미터로 받아 필터링된 목록을 보내주고 있었다.
메인 페이지에 들어가는 api는 '아이스티' 카테고리 중 할인율 높은 상품을 필터링해서 보내주고 있었다.
프론트 분께 메인 페이지에서 api를 호출하는 경우 쿼리 파라미터에 아이스티 카테고리를 넣어달라고 요청했더니
상품 페이지 api로 충분히 메인 페이지에 상품 목록을 보내줄 수 있었다.
이를 통해 설계를 잘 하면 작업 효율을 높일 수 있다는 것을 체감했고
한 api를 다양한 곳에 쓸 수 있게 만드는 방법에 대해 생각해보는 계기가 되었다.
3) django에서 모델링한 경우, 반드시 마이그레이션을 만든 다음 git에 push해야 한다.
처음에 모델링을 마쳤을 때 makemigration을 하지 않은 후 push를 했다.
이후 백엔드 팀원들이 내가 올린 모델을 pull을 받은 후 각자 컴퓨터에서 마이그레이션을 만들어 작업했는데
어느 순간 이상한 git conflict가 나기 시작했다.
알고보니 팀원들이 제각각 makemigration을 했기 때문에 migration 파일에 찍히는 시간이 달라 컨플릭트가 발생하고 있었다.
어떻게든 해결해보려고 했지만 실패하고 결국 모델링을 처음부터 다시 해야 했다.
이미 데이터를 넣고 작업하고 있던 팀원들도 데이터베이스를 리셋해야 해서 번거롭게 한 것이 미안했다.
django 모델을 팀원 전체가 공유하는 경우 반드시 마이그레이션 파일을 만든 다음 공유해야 한다는 것을 배웠다.
'TIL & 프로젝트 회고' 카테고리의 다른 글
| [2차 프로젝트 내일의 집] get_or_create 사용하기 (0) | 2022.08.03 |
|---|---|
| [2차 프로젝트 내일의 집] 카카오 api로 SNS 로그인/회원가입 구현하기 (0) | 2022.08.03 |
| [1차 프로젝트 록차] API 명세서 작성해보기 (0) | 2022.07.27 |
| [1차 프로젝트 록차] 1차 스프린트 회고 (0) | 2022.07.27 |
| [1차 프로젝트 록차] 상품 목록 GET api 제작기 5 - 리팩토링 (0) | 2022.07.27 |