본문 바로가기
사이드 프로젝트/GetABeer

[사이드 프로젝트] EP 18. 사이드 프로젝트를 마무리하며

by Bhinney 2023. 5. 12.

🍺 서비스 이름 : Get A Beer

🍺 개발 기간 : 2023.01.30 ~ 2023.03.10 

🍺 개발 인원 : 총 6인 (FE 3인 + BE 3인)

 

 

GetABeer

 

www.getabeer.co.kr

 

반성하자... 이 글을 올리기까지 두달이 걸리다니...🤦🏻‍♀️


📍평가 도메인과 안주 추천 도메인

  • 평가 도메인과 안주 추천 도메인 모두 로그인 한 사용자만 작성 가능
  • 수정 혹은 삭제 시, 작성자와 로그인한 유저가 일치해야 요청 처리 가능
  • 회원은 하나의 맥주에 한 개의 평가만 작성 가능
  • 회원은 하나의 맥주에 여러 개의 안주 추천 작성 가능
  • 안주 추천 작성 시, 이미지 업로드 할 수 있도록 구현
  • S3를 이용하여 서비스에 필요한 이미지를 업로드 후, URL을 DB에 저장
  • 안주 추천 수정 시, 이미지 수정 가능하도록 구현
  • 평가 글과 안주 추천 글 조회 시, 상태 패턴 사용 및 Query Dsl 사용 (상세 설명은 내려가다 보면 존재함)

📍댓글 도메인과 추천 도메인

  • 평가 글 및 안주 추천 글에 댓글 작성 가능
  • 댓글 조회는 페이지 네이션 없이 댓글 달린 순서로 응답
  • 추천 요청 들어올 시, 회원이 추천한 적이 있는 글이면 추천을 취소하고 추천한 적이 없으면 추천하도록 구현

📍Query Dsl로 동적 정렬 구현하기

  • 안주 추천 글 조회 시, 카테고리 별 조회 및 최신 순 / 추천 순 / 댓글 많은 순 조회 필요
  • 평가 조회 시, 최신 순 / 추천 순 / 댓글 많은 순 조회 필요
  • 만약 로그인을 하였고, 해당 회원이 글을 작성하였다면 자신의 글을 먼저 조회할 수 있도록 구현
  • 평가는 1개의 글만 작성 가능하지만, 안주 추천 글은 여러 개의 글을 작성할 수 있기에 자신의 글 중 추천이 많은 글 1개를 우선적으로 조회할 수 있게 구현해야 함
  • 해당 조건마다 정렬 조건을 만들었더니 코드의 길이가 길어지는 문제 발견
  • OrderSpecifier를 이용하여 최신 순 / 추천 순 / 댓글 많은 순의 정렬 조건에 따라 정렬할 수 있도록 함
  • CaseBuilder를 사용하여, 로그인 한 유저가 존재한다면 자신의 글을 먼저 조회 할 수 있도록 함
  • 안주 추천 글의 경우, 본인의 글을 추천 순으로 정렬하여 첫 번째 글을 가져오도록 구현

처음에 코드를 작성할 때, 최신 순 / 추천 순 / 댓글 많은 순 정렬 조건 별로 메서드를 생성하였던 상태였다. 하지만 이후 카테고리 별 조회 및 로그인한 유저의 글을 먼저 불러오는 요구 사항들을 구현하다 보니 각 상황별로 메서드가 너무 많아지는 문제가 발생하였다. 그리하여 필요한 메서드들을 묶는 작업이 필요했다.

 

가장 먼저 OrderSpecifier를 이용하여 최신 순 / 추천 순 / 댓글 많은 순의 정렬 조건에 따라 정렬할 수 있도록 하는 메서드를 생성하였다. 정렬 조건 타입을 문자열로 받은 후, 해당 문자열에 따라 조건 정렬을 정하는 조건문을 작성하여 해당 타입의 조건에 따라 정렬할 수 있도록 하였다.

 

이후 로그인 유무를 판단하고, 로그인한 유저가 글을 작성하였을 경우 본인의 글을 추천 순으로 정렬하여 가장 추천이 많은 글 한 개를 불러오도록 구현하였다. 그리고 CaseBuilder를 사용하여 그 글을 1순위로 정렬할 수 있도록 하였다. 

 

또한 카테고리 별 조회와 전체 조회를 나누어서 메서드를 생성하였다. 카테고리 별 조회의 경우, 안주 추천에 카테고리 별 분류를 추가해 두었기 때문에 해당 카테고리와 맞는 글을 불러오도록 하면 되었다. 전체 조회의 경우 그럴 필요가 없이 전체 불러오면 되기 때문에 두 개로만 분류하여 작성하였다.

 

위처럼 동적 정렬을 한 결과, 이전처럼 조건 별로 메서드를 써서 정렬하였다면 81개나 될 메서드를 8개로 줄였다.


📍백엔드 서버 배포

  • 서버 배포를 위해 Nginx를 사용
  • letsencrypt, certbot을 이용하여 https 배포
  • EC2를 이용한 서버 배포 및 탄력적 IP 할당
  • RDS와 ElastiCache 연결
  • Github Actions와 Docker를 이용하여 백엔드 서버 자동배포

처음에는 Github Actions와 AWS CodeDeploy를 이용하여 배포를 하였다. 프리티어를 사용하다보니 계속해서 EC2에 과부하가 오는 이슈가 발생하였다. zip파일에 jar파일만 올라가는 것이 아닌 전체 파일을 압축하다 보니, 파일의 용량이 큰 이유였다. (프로젝트 이후 최근에 발견함..)  당시에는 해당 원인을 판단하지 못하여, 용량을 조금이라도 줄이고자 Docker를 이용하기로 결정하였다. Docker  이미지로 빌드한 후, EC2에서 해당 이미지를 받은 후 실행시켰다. 그랬더니 서버에 과부하가 오지 않았고, 자동 배포와 무중단 배포에 성공할 수 있었다.

 

배포 과정에서 또 다른 이슈가 존재했다. EC2에서 GCP Credentials를 찾지 못하는 문제였다. 그래서 json 생성 방식을 수정해보기도 했고, EC2에 변수로 해당 파일을 등록해보기도 했다. 결과적으로는 자동 배포 시에도 json 파일을 생성해 주어야 했고, EC2에도 해당 파일과 변수를 등록해두어야 했다.


📍상태 패턴 사용하기

  • 안주 추천 글 조회를 구현하는 도중, 조건문으로 인해 코드가 길어지는 문제점 발견
  • 상태 패턴을 사용하여 각 상태에 맞는 클래스 생성
  • 각 클래스에 맞는 코드 작성
  • 코드의 길이 약 27% 감소

처음에 코드를 작성할 때에는 서비스 단에 조건 별로 조건문을 사용하여 판단한 후 데이터를 불러왔다. 그렇게 작성하니 서비스 클래스의 코드의 길이가 400줄을 바라보았다. 로그인 유무와 각 정렬 조건 별로의 조건문, 그리고 로그인 유저가 글을 썼을 경우 그 글을 먼저 불러와야하는 조건까지 다 일일히 나누니 길어졌던 것이다. 그래서 코드의 길이를 줄일 목적으로 상태 패턴을 선택하였다.

 

가장 먼저 인터페이스를 생성한 이후, 해당 인터페이스를 상속 받은 클래스를 생성하였다. 전체 조회 && 로그인 유저, 전체 조회 && 로그인 안 한 회원, 카테고리 별 조회 && 로그인 한 회원, 카테고리 별 조회 && 로그인 안 한 회원 이렇게 4가지의 클래스를 생성해주었다. 그리고 각 클래스에 맞게 데이터를 불러 올 수 있도록 상속 받은 메서드를 오버라이딩하여 작성해주었다.

 

그리고 각 상태를 판별해 줄 클래스를 만든 후, 상태에 따른 클래스의 메서드를 사용할 수 있도록 코드를 작성해주었다. 

 

그랬더니 코드의 길이가 약 190줄 정도로 약 27%의 코드 길이를 줄일 수 있었다.

 

프로젝트 종료 이후, 평가 조회 또한 상태 패턴을 적용하여 리팩터링 하였다. (아직 프로젝트의 메인 브랜치에는 PR하지 않고, 리팩터링 브랜치에만 올려둔 상태이다.) 


📍Redis 메세지 큐와 WebSocket를 이용해서 채팅 구현하기

  • 관리자 - 회원 사이에 메세지를 주고 받아야 하는 요구 사항 존재
  • Web Socket과 Redis를 이용하여 채팅 구현
  • 회원 가입 시, 관리자 롤이 아니면 자동으로 채팅방 생성 및 구독
  • 관리자는 모든 채팅방 접근 가능

프로젝트 기간 내에 완성을 하지 못하였다. 그래서 그 이후에 진행하여 메세지가 보내지고 관리자가 메세지 확인할 수 있는 것까지 구현하였다. 현재는 관리자가 읽지 않은 방과 읽은 방을 나누어서 구현해보려고 수정 중에 있다.


반성 중이다.. 프로젝트 끝나고 바로바로 이 글을 작성해야했는데.. 작성하고 싶은 글은 많고 밀리다보니 계속해서...(결국엔 핑계임..)

 

빼먹은 내용은 계속해서 추가할 예정이다.

 

이제부터 다시 블로그 잘 써야겠다..!

댓글