카테고리 없음

issue-tracker 프로젝트 회고

Jerry21 2022. 7. 3. 19:39

06/13 ~ 07/01 기간 동안 진행한 issue-tracker 프로젝트 회고록

 

코드스쿼드의 마지막 프로젝트로 3주 간 BE 2명과 FE 2명이 함께 issue-tracker 프로젝트를 진행했다. issue-tracker는 GitHub Repository의 issue 기능을 만드는 프로젝트로 이슈 필터 기능을 중점적으로 구현하고자 했다.

 

프로젝트 저장소


미션에서 한 일

  • 요구사항 분석, 도메인 설계, 테이블 설계, API 설계
  • MockService를 통한 MockAPIServer 구현
  • Swagger를 통한 API 문서 작성
  • VPC 서버 아키텍처
  • GitHub Actions와 CodeDeploy를 통한 CI/CD
  • 로그인 기능
    • JWT + GitHub OAuth를 통한 로그인 기능
    • Redis를 통한 Refresh token 관리
    • annotation을 이용한 로그인 인증
  • S3를 이용한 파일 업로드 기능
  • Spring Data JPA, QueryDSL
  • 이슈 필터링을 위한 동적쿼리
  • Paging
  • 삽질기록
  • 학습정리 기록

 


😍 좋았던 것

  • 좋은 프로젝트 멤버들

프로젝트 멤버 모두 올빼미족이라서 데일리 스크럼을 첫날 제외하고 오후 5시 30분에 진행했다. 매일 BE 진행상황, FE 진행상황을 공유하면서 API 문서에 대해 토론도 진행했다. 매일 진행상황을 공유하면서 개발 속도를 맞출 수 있어서 좋았다. 또 프론트와 협업이 많이 필요한 로그인 기능을 구현할 때는 같이 모여서 충분히 토론한 이후에 구현을 진행하는 등 소통이 잘 되어서 좋았다. 이 과정에서 너무 백엔드 중심의 API설계를 하거나 잘못된 로그인 flow를 프론트와 토론하는 과정에서 바로잡을 수 있었고 클라이언트의 시각에서 다시 한 번 생각해 볼 수 있어서 좋았다. 또 클라이언트의 입장에서 생각하기 위해서는 클라이언트에 대한 지식이 있어야 겠다는 생각을 하게 되었다. 나중에 간단하게 프론트 공부도 해야겠다.

 

  • ERD 설계

프로젝트 첫 날 요구사항 분석, 기본 설계를 진행했다. 아직 테이블 설계나 ERD 설계에 미숙한 점이 많은데 같이 프로젝트를 진행하는 후가 도움을 많이 줘서 같이 기본 설계를 수월하게 진행할 수 있었다. ERD 설계가 있으니 프로젝트의 규모나 구조가 더 잘 보이고 내가 지금 무엇을 하는지 확실하게 인지하면서 프로젝트를 진행할 수 있어서 좋았다.

 

  • Mockup API Server (Swagger + MockService)

지난 미션에서는 postman을 통한 Mockup API Server를 구축했었다. 프로젝트를 진행하면서 API를 변경하는 일이 생기면 코드 레벨에서 고치고 postman에서 API 문서를 한 번 더 고쳐야 한다는 불편함이 있었다. 이때문에 바로바로 수정을 하지 못해서 지난 미션에서는 Mockup API Server와 서비스하고 있는 실 서버의 API가 다른 경우가 있었다. 이에 코드레벨에 가깝게 Mockup Server를 두어야 한다고 판단하여 MockService를 구현하여 자바에서 Mock Data를 직접 생성한 후 빠르게 배포를 하여 Mockup API Server를 만들었다. 이 때 Swagger도 연동을 하여 코드 레벨로 API 문서를 관리하니까 API의 변경이 있어도 바로 반영을 할 수 있었다.

 

  • 페어 프로그래밍

같은 BE 멤버인 후와 많은 과정을 페어 프로그래밍으로 진행했다. Intellij의 code with me를 통해서 페어 프로그래밍을 하거나 협업을 했다. 코드를 작성하면서 의견이 다른 부분은 사소한 것 하나까지 서로의 입장을 이야기해보고 무엇이 더 좋을지에 대해 이야기를 많이 나누었는데 이 과정에서 나와 다른 시각을 배울 수 있어서 좋았다.

 

  • 학습 정리 기록 및 토론

처음 써보는 기술 또는 공부가 필요한 키워드들을 적어 놓고 각자 공부한 이후에 노션에 정리한 후 서로 설명을 했다. 이 과정에서 혼자 공부하는 것보다 훨씬 더 많이 배울 수 있어서 좋았다.

 

  • 새로운 기술 학습

이번 프로젝트를 진행하면서 파일 S3 업로드 후 링크 반환, CORS, Redis, CodeDeploy, annotation을 통한 인증 처리 등 새로운 기술과 기능을 적용해보았다. 새로운 기술을 학습하고 적용하는 것을 계속 반복하다 보니 점점 익숙해지고 어떻게 해야 할지 감이 잡히는 것 같다.

 


📚 배운 것

  • CORS

처음으로 프론트엔드와 작업을 하게 되면서 CORS 문제를 해결해야 했다. 스프링이 간편하게 CORS 문제를 해결해주지만 CORS가 무엇이고 왜 서버에서 해결을 해야 하는지 궁금해서 이와 관련되어 공부를 진행했고 프로젝트에서 CORS 문제를 해결하도록 설정해주었다.

 

  • QueryDSL에서 동적쿼리 & MultipleBagFetchException 해결

이전에도 QueryDSL을 사용했었지만 이 번 미션처럼 많은 엔티티를 fetch join하고 동적쿼리를 사용해야 할 상황이 없었다. 이번 미션을 진행하면서 N+1 문제를 해결하고자 1 : N 관계에 있는 엔티티 여러 개를 fetch join 해야 했었는데 MultipleBagFetchException이 발생하였었다. QueryDSL에서는 한 개의 1 : N 관계만을 fetch join할 수 있으므로 자료구조를 List가 아닌 Set으로 변경하여 여러 1 : N 관계를 fetch join하여 N + 1 문제를 해결했다. 또 굉장히 많은 조건을 동적쿼리로 만들어 볼 수 있어서 QueryDSL 사용법을 조금 더 익힌 것 같다.

 

  • Redis

Redis를 학습한 이후에 프로젝트에 적용하여 기존 메모리에 저장하고 있던 refresh token을 Redis에 저장하도록 변경했다. 기존 메모리에 저장하던 방식은 서버가 여러 대일 경우 한 곳의 서버에만 계속 요청을 보내야 한다는 단점을 Redis로 분리하여 서버가 여러 대일 때 어떤 서버에 요청하여도 제대로 된 응답을 내릴 수 있게 하였다. 또한 Redis는 일정 기간 이후에는 삭제할 수 있는 기능을 사용해서 간편하게 refresh token을 관리할 수 있게 되었다.

 

  • annotation을 이용한 로그인 인증 처리

interceptor만을 통해 로그인 인증 처리를 하고 있었다. 이렇게 하다 보니 회원가입을 진행하는 POST /api/members 는 로그인 인증 처리를 하면 안 되고 멤버 리스트 조회를 위한 GET /api/members 는 로그인 인증 처리를 해야 하는 상황이 생겼다. interceptor에서 request를 통해 /api/members 일 경우 HttpMethod가 GET이면 인터셉터 실행, POST면 인터셉터 실행하지 않는 등의 로직을 넣고 싶지 않아서 @LoginRequired 라는 커스텀 어노테이션을 정의하고 로그인이 필요한 요청인 메서드에만 @LoginRequired 어노테이션을 통해 로그인 인증 처리를 하도록 인터셉터를 수정했다.

 


💦 부족했던 것

  • CORS를 세팅한 이후에 문제없이 잘 동작하다가 3주 차 수요일에 preflight 요청에서 CORS 문제가 발생했는데 해결하지 못했다. OPTIONS 요청이 제대로 처리가 되지 않는 것 같은데 마지막까지 제대로 해결을 하지 못해 아쉽다.
  • 3주 차에 체력을 모두 소진한 상태라서 집중이 잘 되지 않았다. 체력관리를 한다고 했는데 실패했다.