Americanote ☕️

프로젝트: 아메리카노트 (내 취향에 딱 맞는 아메리카노 카페 찾기 서비스)
프로젝트 기간: 2024.03.21 ~ 2024.03.30, 리팩토링 2024.04

중간산출물_Americanote



기술 스택

Backend

  • Java 17, Spring Boot, Spring Data JPA, QueryDSL
  • Spring Security, JWT

DevOps

  • NaverCloudPlatform Ubuntu Server, MySQL, Global Domain
  • Nginx, LetsEncrypt

서비스 아키텍처

service-architecture

KPT(Keep, Problem, Try)

Keep

팀빌딩 시 적극적으로 행동하기

비사이드 포텐데이에 관한 소개나 후기를 찾아보니 첫날부터 4일간 팀빌딩을 직접 할 수 있다고 해서 자기소개를 미리 적어두고, 팀빌딩이 시작되고 자기소개를 제일 먼저 올렸다. 평소엔 생각이 많아서 무언가를 제일 먼저 하는 편이 아닌데, 이번 프로젝트를 굉장히 잘하고 싶은 마음이 커서 조금 더 적극적으로 행동했다. 그 결과 몇 분께 DM을 받았고, 그중에 현재 팀의 백엔드분이 이미 팀이 구성되어 있다고 한 부분이 매력적으로 느껴져셔 합류하게 되었다.

Swagger 사용

인턴 때 팀원들에게서 배웠던 Swagger 설정을 이번에는 직접 해볼 수 있었다. 생각보다 어렵지 않고 설정만 해주면 그룹별로 나눠서 볼 수도 있고, 프론트분께 API를 효율적으로 전달할 수 있었다. 조금 아쉬운 점을 찾자면 프론트 분이 swagger를 사용해 본 적이 없으셔서 잘 활용했는지 의문인데, 이 부분은 설명서 같은 걸 만들어 드렸면 더 좋았을 것 같다.

swagger

Git Flow로 협업하기

Git Flow도 인턴 때 배웠었는데, 이번에는 Jira도 사용하지 않았기 때문에 포텐데이에서 제공해준 방법으로 간단하게 develop에서 feature를 따서 PR 후 코드 리뷰를 한 다음 merge 하는 방식으로 진행했다.

서로 코드를 보면서 나은 방법을 고민하기도 하고, 왜 이 코드를 썼는지 설명해주기도 해서 정말 유익한 시간이었다. 실무와 인턴 때 배웠던 부분에 대해 백엔드 팀원에게 공유해주다보니 내가 부족한 부분, 더 알아야 할 부분도 함께 알게 돼서 오히려 좋은 기회였다는 생각이 든다.

gitflow

JWT 구현

예전 팀플이나 실무에서도 JWT를 종종 사용했지만 내가 직접 구현하는 건 처음이었는데, 생각보다 복잡해서 여러 프로젝트를 참고해서 만들었다.

Naver Cloud로 Cloud Server 작업

이번 프로젝트 때 서버를 거의 담당하게 되었다. 실무 때나 개인 프로젝트 때는 AWS만 다뤄봤는데, 이번에는 비사이드 측과 연계된 Naver Cloud Platform을 사용해봤다. 처음에 클라우드 서버가 Naver Cloud Platform이라고 했을 때는 사용해보지 않은 플랫폼이라 걱정이 조금 됐었는데, 막상 사용해보니까 별로 다를 것도 없고 사이트에도 설명을 잘 적어놔서 생각보다 수월하게 서버, DB, 네임서버까지 사용할 수 있었다. (비용 관련해서는 AWS가 확실히 더 저렴한 것 같긴 하다..)

바로 리팩토링하기

프로젝트 종료 다음날 백엔드 팀원과 바로 디코로 만나 리팩토링할 부분을 정리했다. 그 결과 아쉬워했던 부분을 4월 안에 거의 해결할 수 있었고, 4월 초에 쿼리최적화나 CI/CD 부분을 리팩토링해서 조금 더 나은 코드로 발전시킬 수 있어서 정말 좋은 경험이 되었다.

Problem

  1. HTTPS 없이 API 구현
    개인적으로 가장 아쉬우면서 경험이 쌓였던 부분이다. 개발 초기에 도메인을 구매하려고 생각은 했으나 비용도 있고 굳이 사야하나 해서 public ip로 API를 제공했었는데, 마감 전날 프론트 쪽에서 백으로 요청을 보낼 때 백의 도메인이 HTTPS가 아니라 요청이 아예 막혀서 문제가 됐었다.. 이 부분 덕분에 그날 새벽 4시까지 서버와 싸우느라 시간 낭비한 부분이 너무 아쉬웠다.

  2. Validation과 Error 처리
    10일 동안 기능 구현하기 급급하다보니 가장 중요한 데이터 validation이나 error 처리가 부족했다.

  3. 수동 배포
    이 부분 또한 가장 해보고 싶었던 부분인데 결국 자동 배포에 실패하고 개발 당시에는 수동으로 배포했었다..

  4. accessToken을 오히려 불편하게 사용함
    실무에서 JWT의 accessToken에서 바로 userId를 뽑아서 사용한 적이 있는데, 역시 직접한 부분이 아니다보니 이번에도 10일 안에 적용하기 힘들었다. 그래서 시간 내에 accessToken을 제대로 사용하지 못한 부분이 정말 아쉬웠다.

  5. N+1 문제
    내가 작성한 부분은 아니었지만 같이 작업한 백엔드분이 작성한 코드에서 N+1 문제가 발생했다. JPA 메소드쿼리로 여러 객체를 불러오다보면 생기는 문제였는데, 빠른 시간 안에 해결하기 힘들어하셔서 결국 리팩토링 때 하기로 하고 프로젝트를 마무리하게 되었다.

Try

  1. HTTPS 적용
    마감 전날 부랴부랴 도메인을 구매하고, 서버에서 Letsencrypt를 시도해봤지만 네임서버 에러로 바로 SSL이 발급되지 않았다. 찾아보니 새벽 4시까지 에러와 싸우다가 결국 다음날 오후에 사용이 가능해서 발급받을 수 있었다..
  2. Validation과 Error 처리
    입력값에 대한 validation이나 에러 처리는 대부분 토큰에 관련된 부분이었다. 그래서 모두 처리해주고 나니 accessToken 부분 필터로 처리하면 될 것 같다는 생각이 들어서 그 부분은 다음번에 진행해주었다.

  3. 배포 자동화
    다양한 방법을 찾아보던 중 Github Actions self-hosted runner를 사용한 배포 자동화를 해보기로 했다. 해당 리포지토리에서 Github Actions Runner를 생성하고, 서버에서 명령어를 입력해서 설치한 후 Github Actions의 workflow를 생성해서 처리했다.
  4. 필터에서 accessToken 처리하기
    이전 코드는 컨트롤러에서 HttpServletRequest를 파라미터로 받아 header에 있는 Authorization을 뽑아 사용하는 방식이었다. 그러다보니 토큰이 필요한 모든 컨트롤러에서 파라미터로 HttpServletRequest를 받아야 해서 코드가 불필요하게 길어졌는데, 이 부분을 필터에서 처리해서 코드를 정말 많이 줄일 수 있었다. 에러 처리 또한 토큰이 있고 없고에 따른 분기 처리가 필요한 곳이 몇몇 있어서 그에 따른 2가지 에러로 분류하니 훨씬 일관성 있고 깔끔한 코드로 처리할 수 있게 되었다.

  5. QueryDSL로 N+1 문제 해결
    카페와 커피 객체를 한번에 가져오다보니 20개의 카페 목록을 가져올 때 쿼리가 100개가 나오는 문제가 있었다. 아무래도 취향에 따라 카페를 추천해주는 코드는 조금 복잡할 수 밖에 없어서 최대한 줄이는 방향으로 진행했고, 메소드쿼리로 작성했던 부분을 조금 더 구체적인 객체로 가져올 수 있도록 수정하거나 QueryDSL로 처리해서 쿼리 갯수를 많이 줄일 수 있었다. QueryDSL에 관련해서는 나도 많이 부족했지만, 실무에서의 경험으로 팀원분께 조금이나마 도움을 줄 수 있어서 다행이라고 생각했다.

  6. And so on 👍
    • Naver Cloud 측에서 제공해주는 서버 비용이 남아서 이번 달 안에 꼭 Docker로 CI/CD를 시도해보려고 한다.
    • JWT도 다 이해된 건 아니라 더 자세히 공부해보고 이번달 안에 반드시 블로그 포스팅까지 해볼 것이다.
    • 현재 아메리카노트 팀원들과 공모전을 진행하고 있는데, 열심히 작업해서 좋은 경험이 되었으면 한다.

소감

포텐데이에 참여한 이유는 1년 정도 실무에서 배운 부분을 코드로 보여주기 위해서였다. 개발에 대한 경험도 정말 좋았지만 팀원들과의 협업과 10일이라는 시간동안 하루에 10시간씩 집중하는 내 모습을 통해서 내가 ‘백엔드 개발자’라는 직무에 정말 재미를 느끼고 있다는 걸 알게 되었다.

그리고 정말 운이 좋게 스펀지 같은 흡수력과 포용력을 가진 팀원을 만나서 내가 조금이나마 알고 있는 지식을 공유하고, 또 설명해주기 전에 지식에 대한 타당한 이유를 찾기 위해 노력하는 시간들이 정말 도움이 많이 됐다.

입사하면 신입이나 주니어는 보통 세팅된 환경에서만 개발을 하기 때문에 나 또한 전회사에서 기초 설정에 대한 부분을 사수나 다른 팀원들이 해줬었는데, 이번 프로젝트로 Swagger 설정이나 서버, JWT 같은 기본이라고 하면 할 수 있는 중요한 부분을 작업하면서 개발자로서 조금 더 나아가는 느낌을 받았다.

또한, 기획이나 프론트 팀원과도 의사소통하면서 내가 알고 있는 지식을 상대방의 설명하는 게 정말 힘들었기 때문에, 앞으로 의미가 잘 전달될 수 있도록 말을 조금 더 잘 고르고 상대의 입장을 생각해 봐야겠다.