부스트캠프 웹・모바일8기(boostcamp) 그룹 프로젝트 4주차 회고

최근혁(GeunH)·2023년 12월 9일

그룹 프로젝트

목록 보기
4/6
post-thumbnail

4주차 MVP 버전 배포!

4주차에는 기존에 feature List와 BackLog에서 MVP 버전으로 우선 개발한 기능들을 테스트하고 MVP 버전을 배포할 계획이 있었다.

그렇기에 3주차부터 시작했떤 MVP 버전 api 기능들을 4주차에 모두 구현하고, git-flow를 통한 브랜치 이동 및 검증을 거친 후, 버전 배포를 진행하기로 했다.

안드로이드 분야와 백엔드 분야의 branch를 dev까지는 따로 만들고 ( ex : develop/be , feature/be-mypage ) 이를 release브랜치부터 통합한 후에 기능들의 error fix가 이루어지고 최종적으로 검증이 완료된 후에 main 브랜치로 병합하여 배포를 하기로 하였다

MVP 버전 배포 후 Final APi 구현 시작

mvp 버전 개발이 완료되었다고 우리 프로젝트의 끝은 아니었다.

Final 기능에서는 mvp버전에서 비교적 간단하게 구현되었던 기능들을 여러 측면에서 향상시켜야 했다. 예를 들어 회원 가입, 리뷰 등록 시에 사진 등록하기, 추천 유저 또는 추천 음식점 api 구현, 리스트 정렬 api 를 구현해야 했다.

Object Storage

그 중 가장 빠르게 해결해야 했던 부분은 '사진 등록' 이었다.

Image 파일의 경우 이진 버퍼 데이터로 구성이 되어있는데, 이 이미지 데이터 자체를 DB에 저장하는 것은 Image의 크기에 따라 DB서버에 비효율적인 메모리 과부하가 이루어진다고 판단했다.

따라서, NCloud의 Object Storage 서비스를 이용해 크고 작은 이미지 데이터를 DB에 직접적으로 저장하지 않는 대신, DB에는 Object Storage에 저장되는 Image의 Path를 text 형식으로 저장하기로 했다.

Object Storage에 하나의 Bucket을 만들고 Bucket 하위 구조에서 폴더로 Review, Profile 로 구분을 하여 관리하기로 했다.

Nest.js에서 aws3라이브러리를 이용해 Ncloud의 Object Storage에 접근을 할 수 있었다.

이 때, 우리가 했던 고민은 Object Storage에 사진을 업로드 하면서 Public Read기능을 켜도 되는가? 였다.

Public Read 속성과 함께 사진을 업로드 할 경우에, 악의적인 사용자가 Object Storage의 사진 경로를 알아낸다면 수많은 요청을 통해서 Obejct Storage를 관리하는 요금을 감당할 수 없을 것이라 판단했다.

결론적으로 Public Read 속성을 제거한 후에 WAS에서는 사진관련 api 요청이 들어오면 DB에서 Object Storage의 Bucket 내 path를 꺼내와 Object Storage의 Path 자체를 주는 것이 아닌, expires : 60s의 제한된 시간동안만 유효한 WAS의 서명화된 URL을 사용자에게 제공하기로 하였다.

사용자의 Refresh Token 저장 DB

이번 프로젝트를 진행하면서 제한된 예산 내에 서비스를 개발해야 했고, 이는 우리에게 여러 고민을 하게 만들기도 하였다.

특히 사용자가 로그인에 성공하여 서비스를 이용하려 할 때에 우리 서버는 일반적인 서버와 같이 사용자에게 Refresh Token, Access Token을 제공한다.

이 경우에 서버에서는 사용자로부터 받는 Access Token과 Access Token 만료 시 재발급을 위한 Refresh Token 의 유효성을 검증해야 한다. Nest.js의 경우 passport 라이브러리를 통한 서버의 secret 이 맞는지 판단할 수 있으나, 이는 토큰의 허용 판단이 아니다.

따라서 서버에서는 이러한 토큰들이 정말 이 사용자의 토큰인지, 예를 들어 로그아웃한 사용자의 토큰을 사용하는 것이 아닌지에 대한 적절한 판단이 이루어져야 했다.

우리가 생각한 해결방안으로는 Refresh-Token을 사용자 id ( 로그인 시 id 아님 )과 함께 DB에 저장하여 Access-token 재발급 시에 검증을 거치는 것이었다.

이를 위해서는 DB 선택을 해야 했는데, 일반적으로는 Redis와 같은 메모리 DB를 사용하여 빠른 접근 속도를 통해 검증을 하는 것으로 파악했지만 지금 현재 우리가 사용하는 PostgreSQL로는 안될까? 라는 생각이 들었다.

제한된 예산 내에서 Refresh-Token 관리 하나만을 위해서 Redis DB Server를 하나 더 구축하기에는 아쉽다는 생각이 들어 RDB에서 Token 관리 테이블을 하나 더 생성하고 관리하기로 했다. 또한, Refresh-Token 검증 자체는 많이 이루어지는 요청이 아니기에 RDB로도 충분히 관리할 수 있다고 판단하였다.

테스트 도구 변경

pg-mem -> Docker로 변경.

기존 단위 테스트를 pg-mem 라이브러리를 활용한 인메모리 가상 DB 테스트 방식을 고려하였고, 실제로 진행하였으나 PostgreSQL DB에서 Restaurant 테이블 컬럼 속성 중 postgis 확장에서 제공하는 point타입의 location field 를 pg-mem에서는 지원하지 않았기에 테스트 자체가 불가능했다. 때문에 postgis 확장을 지원하는 테스트 도구를 찾아야 했고 컨테이너 가상 DB test 방식인 Docker를 찾게 되었다.

Docker를 단위테스트에 사용하는 것은 너무 무거워지기에 다른 테스트 도구들도 찾아 보았지만, 가상 DB 방식을 이용하면서 Postgis 확장을 지원하는 테스트 도구는 Docker가 최적이라 판단하였다.

목표 설정

실제 DB와 유사한 환경이지만 실제 DB는 아닌 컨테이너 가상 DB 환경에서 각 단위 테스트, 통합 테스트, 시나리오 테스트를 진행하자.

기술적 장애물

단위 테스트 진행 시에, Docker를 이용하기 때문에 테스트 진행 속도가 인메모리 가상 DB에 비해 비교적 느리다.

해결책

테스트 실행 환경을 최적화 및 병렬 테스트 실행, 컨테이너 재사용 등의 전략을 사용

마무리

이번 주는 MVP 버전 배포와 동시에 Final 버전 기능을 개발하는 한 주였다.

많은 문서들을 찾아보며 이를 학습한 내용을 바탕으로 코드를 구현하고 또 수정하며 여러 시행착오를 겪었다.

특히, 이번 주차에서 기존 pg-mem으로 단위테스트를 진행하려 했던 것에서 어려움을 겪었는데, 충분한 기술적 교체 이유를 생각하고 Docker로 바꾸게 되었다. 지금처럼 항상 ‘기술적 선택 이유’ 를 마음에 두고 개발을 해야겠다!

profile
목표 : 스스로 성장하는 개발자

0개의 댓글