오늘도 개발
[2차 프로젝트 내일의 집] 프로젝트 최종 회고 본문
1. 프로젝트 개요
2차 프로젝트로는 오늘의 집을 클론코딩하여 '내일의 집'을 만들었다.
기획, 디자인만 오늘의 집을 참고하고 기능은 모두 직접 구현하였다.
클론코딩 사이트로 오늘의 집을 선정한 이유
오늘의 집은 커뮤니티와 스토어가 밀접하게 연동되어 있는 구조이다.
따라서 커뮤니티를 통해 SNS 기능을, 스토어를 통해 커머스 기능을 둘 다 연습해볼 수 있으리라 기대했다.
또 두 기능이 얽혀 있는 구조이므로 복잡한 모델링을 연습해보기 좋으리라 생각했다.
또 소셜 로그인 기능을 구현하며 카카오 API를,
포스트 작성 기능을 구현하며 AWS S3를 사용해보고 싶었다.
개발 인원
프론트엔드 3명, 백엔드 2명(나 포함)
개발 기간
2022.8.1 ~ 8.12(2주)
내 역할
DB 모델링, SNS 로그인 API, 포스트 상세/목록 API, 팔로우/팔로우 포스트 API, 검색 API
프로젝트 종료 후 개인 진행 : 포스트 작성 API, Docker로 배포 연습
과정
[2차 프로젝트 내일의 집] 카카오 api로 SNS 로그인/회원가입 구현하기
[2차 프로젝트 내일의 집] get_or_create 사용하기
[2차 프로젝트 내일의 집] SNS 로그인/회원가입 api에 Unit Test 해보기
[2차 프로젝트 내일의 집] 포스트 목록 api - Django ORM 최적화하기
[2차 프로젝트 내일의 집] 상품 상세 api - Django ORM 최적화하기 심화
[2차 프로젝트 내일의 집] AWS s3로 글쓰기 api 구현하기 - 1. AWS 세팅(IAM 설정, S3 설정)
[2차 프로젝트 내일의 집] AWS s3로 글쓰기 api 구현하기 - 2. Django 세팅(boto3)과 코드 작성
[2차 프로젝트 내일의 집] AWS s3로 글쓰기 api 구현하기 - 3. 리팩토링
[2차 프로젝트 내일의 집] 카카오 api로 SNS 로그인/회원가입 리팩토링
기술 스택
개발 관련 : Python, Django, MySQL, Postman
협업 관련 : Trello, Notion, Slack, Git & Github
Github repository
https://github.com/eungang3/35-2nd-nhouse-backend
시연 영상
https://www.youtube.com/watch?v=xwOui_m09ZI&t=1s



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

API 명세서
2. 프로젝트에서 내가 맡은 역할
1) SNS 로그인 API
구현 사항
1. 유저 정보를 응답하는 카카오 REST API에 django requsts로 요청 보내고 유저 정보 응답받기
2. 유저의 카카오 아이디가 DB에 있으면 "LOGIN_SUCCESS" 메시지와 jwt 반환
3. 유저의 카카오 아이디가 DB에 없으면 DB에 유저 정보 저장 후 "SIGNUP_SUCCESS" 메시지와 jwt 반환
4. unit test 코드 작성해서 테스트 자동화
배운 점
1. 공식 문서를 읽어보고 REST API를 사용해봄
- 카카오 API의 인가 코드, 토큰, 서비스에서 발급하는 jwt 토큰의 역할과 차이점에 대해 알게 됨.
・ 인가 코드는 내일의 집이 카카오의 유저 정보에 접근해도 된다는 증거이다.
・ 카카오 토큰은 유저가 카카오에 로그인했다는 증거이다.
・ 내일의 집에서 발급하는 jwt는 유저가 내일의 집에 로그인했다는 증거이다.
- 낯선 기술을 사용할 때 효율적으로 공부하는 방식에 대해 생각해봄
・ 우선 공식 문서를 읽는다.
・ 모르는 단어나 이해가 가지 않는 부분은 리서치를 해서 제대로 이해한다.
・ 그런 다음 공식 문서를 누군가에게 설명한다고 생각하고 내 언어로 정리해본다.
・ 이제 공부한 기술을 내 프로젝트의 어느 부분에 어떻게 적용할 지 글로 간단하게 정리한다.
・ 구체적인 적용 방법을 모르겠으면 리서치를 한다.
・ 코드를 작성한다.
2. 인증, 인가의 개념에 대해 더 잘 이해하게 됨
- 인증은 유저가 우리 서비스에 등록된 유저인지 확인하는 것.
- 인가는 유저가 어딘가에 접근하려고 할 때 권한이 있는지 확인하는 것.
3. 캡슐화의 개념에 대해 배우고 코드에 적용해봄
- 카카오에 요청을 보내는 부분은 KakaoAPI 클래스로 분리해서 관리 -> 코드 유지보수 쉬워짐
4. django의 requests 모듈을 사용해봄
- requests 모듈을 사용하면 django에서 외부 REST API를 호출할 수 있음을 알게 됨.
- django에서 API를 호출할 때 요청 헤더와 바디에 어떻게 정보를 담아 보낼 수 있는지 배움.
5. 테스트 코드를 작성해서 unit test를 진행해봄.
- magic mock을 사용해서 외부 api 호출 없이 테스트를 진행하도록 설정했습니다.
- 테스트 가능한 경우의 수를 떠올리고 정리해서 코드로 풀어보았습니다.
- 테스트 자동화의 중요성을 느꼈습니다.
2) 포스트상세/포스트 목록 API
구현 사항
1. 쿼리 파라미터에 필터링 항목을 입력하면 주거 형태, 평수, 가족형태, 작업 분야, 작업자에 따라 포스트를 필터링해서 응답
2. 페이지네이션 적용
3. 요청 성공 시 페이지 정보, 상품 목록과 코드 200을 반환
4. 존재하지 않는 카테고리나 페이지 요청 시 404 에러 반환
5. unit test 코드 작성해서 테스트 자동화
배운 점
1. 정참조와 역참조 관계에 대해 더 잘 이해하게 됨.
- 역참조 시에는 related_name을 사용하지 않는 경우 _set 매니저를 사용함.
2. django ORM 최적화의 원리와 필요성 이해
- select_related를 적용해보며 DB에서 테이블을 inner join해서 한 번에 가져와 캐싱하는 과정을 이해했습니다.
- prefetch_related를 적용해보며 DB에서 테이블을 가져와 캐싱하는 과정을 이해했습니다.
- 로그를 찍어보며 왜 django ORM 최적화가 필요한지 이해했습니다.
3) 팔로우 API
구현 사항
1. 팔로우 성공 시 "FOLLOW_SUCCESS" 메시지와 201 코드 반환
2. 이미 팔로우하는 유저인 경우 언팔로우. "UNFOLLOW_SUCCESS" 메시지와 200 코드 반환
3. 존재하지 않는 유저를 팔로우하는 경우 "INVALID_USER_TO_FOLLOW" 메시지와 400 코드 반환
배운 점
1. is_created를 사용해 코드를 단축
2. 자기 자신을 참조하는 다대다 관계의 모델을 구축하고 사용해봄
4) 팔로우 목록 API
구현 사항
1. 팔로우하는 유저가 있는 경우 -> 팔로우하는 유저의 포스트 리스트 응답
2. 팔로우하는 유저가 없는 경우 -> 팔로우 수가 가장 많은 유저 10명의 포스트를 각 4개씩 보내줌
배운 점
annotate 메서드 사용법을 익힘
5) (프로젝트 후 개인적으로 진행) 글쓰기 API
구현 사항
1. AWS S3에 사진 업로드하기
- AWS에서 IAM 사용자 설정
- S3 버킷 생성하고 권한 설정
- django에서 boto3의 resource 메서드 사용해서 파일 업로드
- 업로드하는 파일이 항상 고유한 파일명을 가질 수 있도록 uuid 사용
2. DB에 S3에 올라간 사진의 url과 요청 body로 받은 정보 넣기
- 여러 장의 사진을 db에 넣는 부분에 transaction 사용해서 한 쿼리라도 실패하는 경우 전체 쿼리를 rollback하게 만듦.
- 예를 들어, 5장의 사진의 url을 db에 넣다가 3번째 사진에서 오류가 나면 1, 2번 사진도 db에 들어간 적 없는 것처럼 됨.
배운 점
1. AWS의 기능을 더 자세히 알게 됨.
- IAM 사용자를 생성하고 정책을 만들어 사용자에게 부여해봄.
- S3에서 버킷을 만들고 액세스 권한을 설정해봄.
2. django에서 S3로 파일을 올리는 방법을 익힘.
- boto3를 설치하고 django에서 S3를 사용할 수 있게 설정.
- 사용법이 어려웠지만 스스로 서치해서 기능 구현을 완료한 것이 뜻깊었다.
3. transaction의 개념을 배우고 프로젝트에 적용해봄.
4. 파일 관리 방법에 대해 고민해봄.
- db에 데이터를 넣다 오류가 나서 필요 없는 데이터가 들어가는 것은 transaction으로 관리하면 된다.
- s3에 파일을 올리다 오류가 나면 이미 올라간 파일은 되돌릴 수 없다.
- 대신 배포 후 리눅스 환경에서 crontab으로 일정 주기마다 필요 없는 파일을 지울 수 있다는 것을 배웠다.
5. 캡슐화를 시도해보았습니다.
- 처음에는 PostWriteView에 s3에 업로드하는 코드와 db에 업로드하는 코드가 섞여있었습니다.
- 하지만 한 함수는 하나의 기능만 하는 것이 관리하기도 쉽고, 재사용하기도 좋습니다.
- s3에 업로드하는 기능은 FileUploader 클래스를 만들어 캡슐화했습니다.
3. 프로젝트 회고
Liked
1) 다른 팀원의 코드도 빠짐없이 이해하고 넘어간 점
1차 프로젝트때는 다른 팀원의 코드를 완전히 이해하고 넘어갈 여유가 없어서 아쉬웠다.
다른 팀원의 코드를 살펴볼 때도 버그가 난 부분만 같이 살펴보고 나머지는 그냥 넘어갔었는데 이번 프로젝트는 달랐다.
백엔드 팀은 나 포함 두 명이었는데,
둘 다 무작정 코드를 찍어내는 게 아니라 제대로 이해하면서 코드를 짜야 한다고 생각했다.
이 부분이 합의가 되었기 때문에 '안 되는 점'이 아니라 '이해가 되지 않는 점'에 대해 서로 많이 질문을 던졌다.
안 되는 것을 해결하기 위해서는 버그가 난 부분만 살펴봐도 되었는데,
이해가 되지 않는 것을 해결하기 위해서는 전체 코드를 살펴보고 로직을 이해해야 했다.
상대 팀원의 코드가 이해가 되지 않아 그냥 내가 처음부터 끝까지 코드를 새로 짜보기도 했다.
그런 다음 상대 팀원의 코드와 비교해보면 상대분의 코드를 분명하게 이해할 수 있었고,
문제에 대한 답을 얻을 수 있기도 했다.
예를 들어 상품 상세를 가져오는 API에서 prefetch_related()와 select_related()를 사용해야 한 적이 있었다.
상대분이 'select_related가 안 돼요'라고 물어보셨으면 그냥 해결 방법을 같이 인터넷에 검색해보고 넘어갔을 것이다.
하지만 '왜 여기선 select_related, 여기선 prefetch_related를 써야 할까요'라고 물어보셨기 때문에
두 사람 다 정참조, 역참조 관계에 대해 제대로 공부하고 넘어갈 수 있었다.
그러느라 기능 구현엔 시간이 좀 걸렸지만 그 다음 기능을 만들 때는 생각보다 훨씬 빨리 진행이 되었다.
정참조, 역참조 개념을 제대로 이해하고 넘어갔기 때문에
'정참조 관계의 테이블이 역참조하는 테이블이 정참조하는 테이블'처럼 복잡한 관계도 수월하게 표현할 수 있었기 때문이다.
2) 프로젝트 초반부터 문서화를 잘 한 것
1차 프로젝트때는 프로젝트 중후반에야 문서화의 필요성을 느꼈기 때문에 커뮤니케이션에 미흡함이 있었다.
이번에는 모두 1차 프로젝트에서 문서화의 중요성을 느끼고 왔기 때문에, 프로젝트 초반부터 API 명세서를 만들고 진행했다.
사실 프로젝트 초반에 너무 마음이 급해서 일단 API부터 만들고 명세서를 쓸까 하는 생각이 들었는데
결과적으로 명세서부터 작성하는 것이 더 효율적이었다.
어떤 형식으로 요청 메시지를 받는지, 응답 메시지를 보내는지 먼저 작성해보며
내가 만들 기능에 대해 더 잘 정리가 되었기 때문에 코드를 짤 때 덜 헤멜 수 있었기 때문이다.
또 명세서부터 작성했기 때문에 1차 프로젝트 때 처럼 E2E 테스트 이후 둘 중 한 쪽이 엄청나게 코드를 수정해야 하는 경우도 없었다.
이것은 팀원 모두가 문서화의 필요성에 동감했고 잘 참여했기 때문이라고 생각한다.
3) 테스트를 자동화한 것
unit 테스트의 개념을 배우고 프로젝트에 일부 적용해보았는데 굉장히 뿌듯하고 재미있었다.
나는 반복적이고 비효율적인 업무를 정말 싫어하기 때문에
단순 작업을 컴퓨터로 편하게 해결할 수 있을 때 진심으로 신이 난다.
ui 디자이너로 일할 때 QA 업무도 맡았었는데
테스트 해야 할 상황도 너무 많고 일일이 하고 있기엔 너무 지루했던 기억이 있다.
1차 프로젝트때도 E2E, Integration 테스트만 해보았는데 수동으로 하나씩 테스트해야 하는 과정들이 비효율적이라는 생각이 들었다.
그 와중에도 자동화를 해보고 싶어서 포스트맨 batch request를 써보았지만 그래도 부족했다.
테스트 코드를 짜는 방법이 낯설어서 처음에는 어려웠다.
하지만 테스트 코드 완성 후, 컴퓨터가 몇 번이고 테스트를 실행해서 보여주었을 때가
프로젝트를 진행하면서 제일 뿌듯한 순간 중 하나이다.
Lacked
1) 2차 스프린트 때 작업 공유를 놓친 점
2차 스프린트 초반쯤, 급한 마음에 제대로 데일리 미팅을 하지 않은 적이 있었다.
별 것 아니라고 생각했는데 다른 팀원이 무슨 작업을 하는지 파악하지 못해서 일정 관리에 문제가 생겼다.
그래서 중간에 멈추고 다같이 길게 회의를 한 번 해야했는데,
회의를 매일 하는 것보다 더 비효율적이었다.
아무리 급하더라도 간단하게나마 작업 사항을 공유하는 것이 더 낫다는 것을 배웠다.
2) 낯선 기술을 접했을 때 스트레스를 받은 점
이번 2주동안은 새로운 개념을 많이 배웠고(django ORM 최적화, git rebase 등),
낯선 도구(카카오 api, S3, docker 등)도 빠르게 익혀 사용해보아야 했다.
초반에는 처음 보는 것들을 잘 할 수 있을까 걱정이 되어 스트레스를 많이 받았는데
프로젝트가 끝나고 생각해보니 처음 해보는 것들이 제일 재미있었다.
앞으로도 낯선 업무를 만나면 걱정이 많이 되겠지만
사실 낯선 일이 제일 재미있다는 것을 기억해두고 싶다.
3) 트렐로, 노션 알림 설정을 활용하지 못한 점
문서화는 잘 했는데, 문서를 업데이트하면 일일이 팀원들에게 말로 알려준 것이 비효율적이었다.
말로 알려주면 집중하던 팀원의 작업 흐름이 끊길 수도 있고, 전달받은 사실을 잊어버릴 수도 있기 때문이다.
전 팀원이 트렐로, 노션 알림을 켜놓고 작업했으면 커뮤니케이션을 더 잘 할 수 있었을 것 같다.
Learned
1) 같이 가야 멀리 간다는 것
2차 프로젝트를 진행하며 정말 공부를 많이 했다고 느꼈는데 이것은 백엔드 팀원 덕분이다.
나 혼자였으면 생각해보지도 못했을 부분을 파고들어 질문하고, 새로 알게 된 점은 꼭 공유해주셨다.
눈 앞에 닥친 문제를 해결하기 위한 질문이 아니라 '왜'에 대한 질문을 던지셔서
둘 다 많은 공부가 되었고, 나도 앞으로 '왜'를 질문하는 팀원이 되어야겠다 생각했다.
2) 낯선 기술을 사용해야 할 때 효과적으로 공부하는 방법
카카오 api를 이용해서 SNS 로그인 기능을 만들어야 했을 때 처음에는 급한 마음에 일단 검색해서 코드부터 따라쳤다.
하지만 곧 제대로 이해하기 전에 코드부터 치는 것이 비효율적이라는 것을 느낄 수 있었다.
나는 코드를 내 경우에 맞게 변형해야 하는데 어디서부터 어떻게 해야 할 지 이해가 되지 않았기 때문이다.
그래서 다시 다음과 같은 과정을 거쳐 기능을 구현해보았더니
공부하는 데는 시간이 걸렸지만 코드 자체는 금방 칠 수 있었다.
- 우선 공식 문서를 읽는다.
- 모르는 단어나 이해가 가지 않는 부분은 리서치를 해서 제대로 이해한다.
- 그런 다음 공식 문서를 누군가에게 설명한다고 생각하고 내 언어로 정리해본다.
- 이제 공부한 기술을 내 프로젝트의 어느 부분에 어떻게 적용할 지 글로 간단하게 정리해본다.
- 구체적인 적용 방법을 모르겠으면 리서치를 한다.
- 코드를 작성한다.
돌아가는 것 같아도 개념을 제대로 이해해야 더 빨리 갈 수 있는 것 같다.
앞으로 다른 프로젝트를 할 때도 이 과정을 적용해보면 좋을 것 같다.
'TIL & 프로젝트 회고' 카테고리의 다른 글
| [2차 프로젝트 내일의 집] 카카오 api로 SNS 로그인/회원가입 리팩토링 (0) | 2022.08.10 |
|---|---|
| [2차 프로젝트 내일의 집] AWS s3로 글쓰기 api 구현하기 - 3. 리팩토링 (0) | 2022.08.09 |
| [2차 프로젝트 내일의 집] AWS s3로 글쓰기 api 구현하기 - 2. Django 세팅(boto3)과 코드 작성 (0) | 2022.08.08 |
| [2차 프로젝트 내일의 집] AWS s3로 글쓰기 api 구현하기 - 1. AWS 세팅(IAM 설정, S3 설정) (0) | 2022.08.08 |
| [2차 프로젝트 내일의 집] 상품 상세 api - Django ORM 최적화하기 심화 (0) | 2022.08.08 |