/35-2nd-nhouse-backend

[쇼핑몰 & SNS] 내일의 집 서버

Primary LanguagePython

내일의 집 nhouse (위코드 35기 2차 프로젝트)

  • 내일의 집은 오늘의 집 쇼핑몰을 클론코딩한 프로젝트입니다.
  • 개발에 집중하기 위해 기획, 디자인은 참고하고 기능은 직접 구현하였습니다.

1. 선정 이유

  • 커뮤니티와 스토어가 밀접하게 연동되어 있는 구조

    • 복잡한 모델링 공부 가능
    • SNS(커뮤니티) 사이트와 커머스(스토어)사이트를 둘 다 구현해볼 수 있음
  • 소셜 로그인 기능

    • 외부 API를 이용하여 인증, 인가하는 법을 익힐 수 있음
  • 포스트 작성 기능

    • AWS S3를 사용해서 장고와 외부 애플리케이션을 연동하는 법을 익힐 수 있음

2. 개발 인원

  • 백엔드 2명 : 김민지, 조예슬
  • 프론트엔드 3명 : 오창훈(PM), 김광희, 정훈조

3. 기간

2022.8.1 ~ 8.12(2주)


4. 백엔드 역할

  • 김민지

    • DB 모델링
    • 글쓰기 API(s3)
    • 카테고리 API
    • 상품상세/상품목록 API
    • AWS 배포
  • 조예슬

    • DB 모델링
    • SNS 로그인 API
    • 포스트상세/포스트 목록 API
    • 팔로우 API/팔로우 포스트 API
    • 검색 API
    • 프로젝트 후 개인적으로 진행 : 글쓰기 API(s3)

5. 백엔드 기술 스택

  • Back-end : Python, Django, JWT, Bcrypt, Miniconda
  • Database : MySQL
  • Common : Trello, Slack, Git & Github

6. 시연 영상

https://www.youtube.com/watch?v=xwOui_m09ZI&t=1s


카카오-로그인

팔로잉-추천


7. DB 모델링

https://dbdiagram.io/d/62b95a9c69be0b672c484056 스크린샷 2022-08-12 오후 2 41 28

8.1 내 역할 - SNS 로그인 API

구현 사항

  1. 유저 정보를 응답하는 카카오 REST API에 django requsts로 요청 보내고 유저 정보 응답받기
  2. 유저의 카카오 아이디가 DB에 있으면 "LOGIN_SUCCESS" 메시지와 jwt 반환
  3. 유저의 카카오 아이디가 DB에 없으면 DB에 유저 정보 저장 후 "SIGNUP_SUCCESS" 메시지와 jwt 반환
  4. unit test 코드 작성해서 테스트 자동화

배운 점

  • 공식 문서를 읽어보고 REST API를 사용해보았습니다.

    • 카카오 API의 인가 코드, 토큰, 서비스에서 발급하는 jwt 토큰의 역할과 차이점에 대해 알게 되었습니다.

      • 인가 코드는 내일의 집이 카카오의 유저 정보에 접근해도 된다는 증거입니다.
      • 카카오 토큰은 유저가 카카오에 로그인했다는 증거입니다.
      • 내일의 집에서 발급하는 jwt는 유저가 내일의 집에 로그인했다는 증거입니다.
    • 낯선 기술을 사용할 때 효율적으로 공부하는 방식에 대해 생각해보았습니다.

      • 우선 공식 문서를 읽습니다.
      • 모르는 단어나 이해가 가지 않는 부분은 리서치를 해서 제대로 이해합니다.
      • 그런 다음 공식 문서를 누군가에게 설명한다고 생각하고 내 언어로 정리해봅니다.
      • 이제 공부한 기술을 내 프로젝트의 어느 부분에 어떻게 적용할 지 글로 간단하게 정리해봅니다.
      • 구체적인 적용 방법을 모르겠으면 리서치를 합니다.
      • 코드를 작성합니다.
  • 인증, 인가의 개념에 대해 더 잘 이해하게 되었습니다.

    • 인증은 유저가 우리 서비스에 등록된 유저인지 확인하는 것입니다.
    • 인가는 유저가 어딘가에 접근하려고 할 때 권한이 있는지 확인하는 것입니다.
  • 캡슐화의 개념에 대해 배우고 코드에 적용해보았습니다.

    • 카카오에 요청을 보내는 부분은 KakaoAPI 클래스로 분리해서 관리합니다.
  • django의 requests 모듈을 사용해보았습니다.

    • requests 모듈을 사용하면 django에서 외부 REST API를 호출할 수 있음을 알게 되었습니다.
    • django에서 API를 호출할 때 요청 헤더와 바디에 어떻게 정보를 담아 보낼 수 있는지 배웠습니다.
  • 테스트 코드를 작성해서 unit test를 진행해보았습니다.

    • magic mock을 사용해서 외부 api 호출 없이 테스트를 진행하도록 설정했습니다.
    • 테스트 가능한 경우의 수를 떠올리고 정리해서 코드로 풀어보았습니다.
    • 테스트 자동화의 중요성을 느꼈습니다.

8.2 내 역할 - 포스트상세/포스트 목록 API

구현 사항

  1. 쿼리 파라미터에 필터링 항목을 입력하면 주거 형태, 평수, 가족형태, 작업 분야, 작업자에 따라 포스트를 필터링해서 응답
  2. 페이지네이션 적용
  3. 요청 성공 시 페이지 정보, 상품 목록과 코드 200을 반환
  4. 존재하지 않는 카테고리나 페이지 요청 시 404 에러 반환
  5. unit test 코드 작성해서 테스트 자동화

배운 점

  • 정참조와 역참조 관계에 대해 더 잘 이해하게 되었습니다.

    • Post 모델은 User 모델을 정참조합니다.
    • Post 모델은 Photo 모델을 역참조합니다.
    • 역참조 시에는 related_name을 사용하지 않는 경우 _set 매니저를 사용합니다.
  • django ORM을 최적화했습니다.

    • select_related를 적용해보며 DB에서 테이블을 inner join해서 한 번에 가져와 캐싱하는 과정을 이해했습니다.
    • prefetch_related를 적용해보며 DB에서 테이블을 가져와 캐싱하는 과정을 이해했습니다.
    • 로그를 찍어보며 왜 django ORM 최적화가 필요한지 이해했습니다.

8.3 내 역할 - 팔로우 API

구현 사항

  1. 팔로우 성공 시 "FOLLOW_SUCCESS" 메시지와 201 코드 반환
  2. 이미 팔로우하는 유저인 경우 언팔로우. "UNFOLLOW_SUCCESS" 메시지와 200 코드 반환
  3. 존재하지 않는 유저를 팔로우하는 경우 "INVALID_USER_TO_FOLLOW" 메시지와 400 코드 반환

배운 점

  • get_or_created를 사용해 코드를 단축해보았습니다.
  • 자기 자신을 참조하는 다대다 관계의 모델을 구축하고 사용해보았습니다.

8.4 내 역할 - 팔로우 목록 API

구현 사항

  1. 팔로우하는 유저가 있는 경우

    • 팔로우하는 유저의 포스트 리스트 응답
  2. 팔로우하는 유저가 없는 경우

    • 팔로우 수가 가장 많은 유저 10명의 포스트를 각 4개씩 보내줌

배운 점

  • annotate 메서드의 사용법을 익혔습니다.

8.4 프로젝트 후 개인적으로 진행 : 글쓰기 API(s3)

구현 사항

  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에 들어간 적 없는 것처럼 됨.

배운 점

  • AWS의 기능을 더 자세히 알게 되었습니다.

    • IAM 사용자를 생성하고 정책을 만들어 사용자에게 부여해보았습니다.
    • S3에서 버킷을 만들고 액세스 권한을 설정해보았습니다.
  • django에서 S3로 파일을 올리는 방법에 대해 알게 되었습니다.

    • boto3를 설치하고 django에서 S3를 사용할 수 있게 설정해보았습니다.
    • 사용법이 어려웠지만 스스로 서치해서 기능 구현을 완료한 것이 뜻깊습니다.
  • transaction을 프로젝트에 적용해보았습니다.

    • 막연하게 알고있던 transaction을 실제로 사용해보며 transaction에 대해 더 잘 이해하게 되었습니다.
  • 파일 관리 방법에 대해 고민해보았습니다.

    • db에 데이터를 넣다 오류가 나서 필요 없는 데이터가 들어가는 것은 transaction으로 관리하면 됩니다.
    • s3에 파일을 올리다 오류가 나면 이미 올라간 파일은 되돌릴 수 없습니다.
    • 대신 배포 후 리눅스 환경에서 crontab으로 일정 주기마다 필요 없는 파일을 지울 수 있다는 것을 배웠습니다.
  • 캡슐화를 시도해보았습니다.

    • 처음에는 PostWriteView에 s3에 업로드하는 코드와 db에 업로드하는 코드가 섞여있었습니다.
    • 하지만 한 함수는 하나의 기능만 하는 것이 관리하기도 쉽고, 재사용하기도 좋습니다.
    • s3에 업로드하는 기능은 FileUploader 클래스를 만들어 캡슐화했습니다.

9. API 명세서

https://www.notion.so/API-aba14d6d95e04d9ca1723f5467d1df3b