함께하개 프로젝트 후기

개발자 강세영·2022년 10월 12일
0
post-thumbnail

‘함께하개’ 웹사이트 바로가기

반려견 MBTI 검사와 커뮤니티 기능을 제공하는 웹사이트

프론트엔드 팀원

백엔드 팀원

  • 강세영

백엔드 사용 기술

  • Python 3.9.13
  • Django web framework 4.1
  • Django Ninja 0.19.1
  • Postgresql
  • MongoDB
  • python-socketio

클라우드

  • AWS EC2, RDS, S3
  • MongoDB Cloud

백엔드 구현 기능

  • 회원 관련 API
    • 회원 CRUD
    • 소셜 로그인(구글, 카카오)
    • 회원 차단(비활성화), 회원 탈퇴
  • 게시판 관련 API
    • 게시글 CRUD
    • 댓글 CRUD
    • 악성 게시글, 댓글 신고 기능
  • 관리자 기능 API
    • 관리자 페이지 기능
    • 사용자 신고 알림 및 확인 기능
  • 채팅
    • 욕설 필터링
    • 채팅 메시지 신고 기능

DB ERD

구현 영상

  • 로그인 후 사용자 정보 수정
  • 게시판 글 쓰기
  • 게시판 댓글 입력, 좋아요
  • 관리자 페이지
  • 채팅 기능

프로젝트 기획

  • 부트캠프를 수료하고 기업협업 인턴십을 했던 회사에서 8월까지 유급인턴으로 일하기로 계약을 하고 근무하게 되었다.

  • 인턴 근무를 하던 중에 다른 동기들은 스터디를 하는 것 같아서 나도 스터디에 참가하게 됐고, 스터디 팀원으로부터 프로젝트 하나 같이 해보자는 제안을 받아서 참여하게 되었다.

  • 위코드 교육과정에서 하게 되는 프로젝트 말고 동기들끼리 자발적으로 진행하는 프로젝트를 하면 좋은 경험이 될 것 같았다.

  • 되돌아 보니 초기 기획 단계에서 적극적으로 참여하지 못한 게 아쉽다. 주제 선정 단계부터 의견을 많이 냈어야 했다.

  • 위코드 1, 2차 프로젝트 같이 클론코딩 위주가 아니라 직접 기획부터 웹 디자인까지 해야 했기 때문에 기획단계에서 생각보다 시간이 오래 걸렸다. 기획과 디자인에 3주 정도, 개발환경 초기 세팅부터 배포까지는 한 달 정도 걸렸다

개발 기술 선택

  • 처음에는 FastAPI로 백엔드 개발을 하려고 했다.

  • FastAPI를 배우다 보니 여러 장점들이 마음에 들었지만, SQLAlchemy라는 ORM을 비롯하여 새롭게 배워야 할 것이 생각보다 꽤 많았다.

  • 인턴 근무까지 하면서 러닝커브를 올리는 게 쉽지 않아서 이번 프로젝트는 익숙한 Django로 개발하기로 했다.

  • Django로 개발한다면 자연스럽게 그동안 못 써본 Django Rest Framework를 공부해서 써볼까 생각했지만 FastAPI를 공부하면서 Django Ninja라는 괜찮은 프레임워크가 있다는 걸 알게 됐다.

  • Django Ninja의 튜토리얼을 조금 따라해보니 내가 원했던 FastAPI의 개발 방식과 여러 가지 장점이 좋아 보여서 DRF 대신 이걸 쓰기로 결정했다.

  • Django Ninja의 특장점

    • 쉽고 직관적인 개발 방식
    • pydantic과 비동기 지원으로 우수한 성능
    • OpenAPI 기반 API 명세서 자동 생성
    • 타입 힌트와 API 명세서로 효율적인 개발 가능
    • Django ORM을 그대로 활용할 수 있음
    • Django Models를 그대로 활용하여 입출력 스키마를 생성할 수 있음
    • FastAPI의 장황한 Depends보다 간단한 코드로 의존성 관리
  • RDBMS는 Django와 궁합이 좋다는 Postgresql을 선택했다. 다만 Django에서 Postgresql을 위해 준비해 놓은 다양한 기능(full text search, GIN Index 지원 등)을 활용하진 못했다.

  • 프론트엔드 팀원과 합의하여 채팅 기능을 위해 웹소켓이 아닌, 웹소켓 기반의 라이브러리인 Socket.IO 를 쓰게 되었다.

  • 웹소켓 보다 Socket.IO를 활용하는 게 개발 속도와 편의성, 기능구현에 장점이 있어서 선택하게 됐다.

  • 웹소켓과 Socket.IO는 완벽하게 호환되지 않으며 나의 목표는 따로 채팅 전용의 node.js 서버를 만드는 게 아니라 Django와 Socket.IO 서버를 통합해서 배포하는 것이었다.

  • 채팅 기능 구현을 위해 웹소켓을 쓸 경우 일반적으로 Django Channels를 많이 쓰는 것 같은데, 상기한 이유로 python-socketio라는 패키지를 활용하게 되었다.

  • 채팅 메시지를 저장하기 위해 MongoDB Cloud를 활용했다.

개발 중 삽질했던 기록과 어려웠던 것들

  • 문서 몇 번 보고 활용법을 완전히 이해했다고 착각하여 코드가 잘못 된 적이 많았다. 무지성 코딩은 지양하자.

  • API 엔드포인트 경로 설정 시 순서가 중요한데 이를 지키지 않아서 405 에러가 났다.

    • 경로가 비슷한 /users/me/users/{user_id}가 있다면 /users/me를 사용하는 함수가 /users/{user_id} 보다 앞에 있어야 한다. FastAPI도 이런 식이었는데 ninja도 같은 방식인 것 같다.
  • Django Ninja의 리퀘스트/리스폰스 Schema에 관련된 다양한 에러를 경험했다.
    대부분 리퀘스트/리스폰스가 미리 정의한 Schema 형식에 맞지 않아 유효성 검사를 통과하지 못하거나(422에러) 리턴하는 Queryset 코드가 잘못되어 생긴 에러였다.

  • Put/Patch 메서드와 Form, File을 사용할 경우 생기는 문제가 있었고 미들웨어 추가로 해결했다.

  • JWT를 httponly 쿠키로 저장하는 과정에서 겪은 시행착오

    • 자바스크립트의 fetch/axios를 그냥 쓰면 리스폰스로 받은 쿠키가 저장되거나 쿠키를 리퀘스트 헤더로 보내지 않는다. 적절한 옵션을 설정해줘야 한다.
    • httponly 쿠키는 클라이언트가 쿠키를 조작하지 못하고 백엔드 서버가 보내준 대로만 저장할 수 있다.
    • httponly 쿠키를 크롬 개발자도구의 application 메뉴에서 볼 수 있게 같은 도메인으로 저장하려면 특정 조건(secure, samesite 등)을 만족해야 한다는 것을 알게 됐다.
    • 이 과정에서 CSRF와 XSS에 대해서도 더 자세히 배울 수 있었다.
  • 프론트엔드 팀원과 통신하는 과정에서 Content-type 문제와 fetch/axios의 잘못된 문법 때문에 통신이 제대로 안되는 오류를 많이 경험했다.

    • OpenAPI 문서에 나오는 curl 명령어를 fetch나 axios로 변환해보면서 어느 부분에서 문제가 있는지 알게 됐고 구글링을 통해 대부분의 문제를 해결했다.
    • 특히 multipart/form-data에 대해 많이 배우게 됐다.
  • 다른 문제들은 대부분 하루 이틀 안에 해결됐지만, socket.io 서버를 통합하는 작업이 3일 정도로 가장 오래 걸렸다. 패키지 버전 때문에 에러 난 것도 있었고 그 외 매우 다양한 종류의 에러를 경험했다.

  • 공식 문서에 나오는 내용을 무작정 따라할 게 아니라 차분하게 생각하면서 적용해야 한다는 것을 깨달았고 영어 독해력도 코딩 못지않게 중요하다는 걸 실감했다.

python-socketio 배포 과정

전체 프로젝트 EC2 배포 과정

프로젝트 개발하면서 얻은 것

  • 처음 써보는 기술을 블로그나 강의가 아닌 공식문서만 보고 학습해서 개발해본 경험이 늘었다.

  • 구글링해서 얻은 코드를 적절히 수정하고 충분한 테스트를 거쳐 검증하고 활용하였다.

  • 함수, 클래스 리팩토링으로 중복 코드를 줄였다.

  • black, flake8, isort 등으로 코드 포맷팅을 하고, 리팩토링을 위해 Sourcery AI의 도움을 받았다.

  • 스키마에서 Field에 alias로 정의하고 모델 클래스에서 @property를 추가하여 활용하는 방법을 배웠다.

  • 배포하고 도메인까지 구입하고 연결해봤다.

  • Nginx에서 https 설정하고 리버스 프록시로 백엔드 서버를 연결했다.

  • HTTP의 다양한 Content-type들에 대해 더 깊이 배웠다.

  • 자바스크립트의 fetch/axios에 대한 이해도가 늘었다.

  • 인증/인가에 대해 더 깊이 배웠다.

  • 프론트엔드 팀원과 더 활발하게 소통하고 함께 문제를 해결하는 경험이 늘었다.

  • 한 끝 차이로 실행이 안되고 에러나는 걸 많이 경험하면서 고통받았지만 대부분 해결했고, 그 만큼 나도 성장했다고 믿는다.

앞으로 보완해야 할 것들

  • requirements.txt에서 서버 실행에 필요한 패키지만 정리
  • URI 엔드포인트 수정
  • Docker 활용
  • DB 프로파일링과 효율적인 인덱싱 적용
  • 변수명들이 적절한 지 확인
  • 리팩토링 함수들의 사이드 이펙트 확인

0개의 댓글