[Kernel360] E2E : Anabada

개요

한 달간 진행했던 E2E 과정 동안 백엔드 엔지니어로써 서비스를 설계할 때 무엇을 중점적으로 봐야할지, 생각해야할 지 고려할 수 있었습니다. 이번 프로젝트는 한 달 간 실제로 배포까지 완성하여 접근할 수 있는 서비스를 구현하는 것이 목표였기에 앞서 과정 중인 진행했었던 프로젝트들 보다 더 많은 기술들을 시도해 볼 수 있는 기회였습니다.

 

이전에 Spring을 혼자 독학하면서 나름 프로젝트의 첫 발을 떼보았다 생각했지만, 이미 해커톤 중 한 차례 뒤통수를 맞고 온 참이라 더 배우는 자세로 임할 수 있었던 것 같습니다. 이번 프로젝트를 시작할 때 투표를 통한 제 주제가 뽑혀서 팀장이 되었고, 약 한 달이라는 기간동안 팀원들과 함께 기획하고 일정을 관리하는 동안 이전 프로젝트들에서는 배울 수 없었던 교훈들을 많이 얻었습니다.

 

아래의 Notion과 Github 링크에서 프로젝트에 대한 더 자세한 문서와 결과물의 세부 내용들을 확인하실 수 있습니다.

Anabada - 지역기반 물물교환 플랫폼.

처음에 주제를 냈을 당시에는 공동구매 플랫폼인 올웨이즈(https://alwayz.co/)를 참고하여 지역기반으로 공동 구매를 할 수있는 플랫폼을 만들고자 했었습니다. 하지만 공동 구매 플랫폼을 실제로 개밥먹기(본인이 만든 서비스를 직접 사용해보는 위)를 진행하기 위해서는 공동 구매를 할 수 있는 물품을 어디에선가 끌고 와야 했고, 공동 구매를 할 수 있도록 결제 시스템을 도입해야하고, 이외에도 한 달이라는 현실적인 시간의 벽 때문에 주제를 급하게 변경해야만 했습니다. 이에 따라서 지역기반이라는 컨셉은 가지고 가되, 물물교환이라는 새로운 주제를 팀원들과 함께 이끌어 냈습니다.

 

앞서 진행했던 프로젝트 중 ministory (https://isevou.tistory.com/entry/Kernel360-Hackathon-ministory-Orury)에서 프로젝트 기획을 진행했던 방식이 지금 팀에 더 합리적이라고 판단하여 그 때의 경험을 바탕으로 팀과 협업을 진행했습니다. 먼저, 모든 기능을 팀원들과 함께 도출해내고, 그 내용을 바탕으로 ERD를 만들어 기획을 시작했습니다. 또한, Figma를 사용하면서 직접 모든 버튼이나 디자인을 직접 하는 방식 대신에 Whimsical이라는 새로운 디자인 툴을 도입하여 화면 프로토타입 개발에 너무 많은 시간을 쏟지 않도록 했습니다.

 

화면 프로토 타입은 https://whimsical.com/anabada-wireframes-VP9MB6yAWYQ1q9XKmtmoTo 여기서 확인하실 수 있습니다. 

이후에 앞서 문서화했던 기록을 바탕으로 기술 스택을 정했습니다.

  • Frontend 
    • HTML / CSS / JavaScript 
    • JQuery - 팀 내부에서 온전히 REST 한 서버로 개발하기로 정하고 클라이언트와 ajax 통신을 통해서 요청과 응답을 주고받기로 결정
    • ChartJS - 관리자 화면의 통계 화면을 보여주기 위해서 사용.
  • Backend
    • JDK 17 - JDK 8 버전 보다 짧은 LTS를 가지고 있지만 그 다음 LTS인 21으로 버전 업을 생각한다면 더 가까운 LTS를 선택하는게 합리적으로 판단되었고 2022년 11월에 출시된 Spring Boot 3.0 부터는 JDK 17이상 선택을 필요로 하고 있어서 결정, 현재 프로젝트 구성은 2.7대로 되어 있지만, 이후에 지원이 끝난다면 선택한 기술들에 대하여 다음 마이그레이션을 할 수 있는 방안을 미리 구성해놓아야한다고 생각
    • Spring Boot 2.7 - 17을 선택했음에도 불구하고 2.7에 남아있었던건 Spring Security와 같은 연관 기술들이 Spring Boot 3.0 이후로 부터 변경점이 존재하고 1달이라는 기간 동안 프로젝트를 완성하려면 러닝커브 또한 고려해야 하기 때문에 팀원들이 조금이라도 더 익숙한 기술을 사용하기로 내부적으로 결정
    • Spring Data JPA / QueryDSL - 필요한 기능들 중 동적인 쿼리가 필요없는 기능은 Spring Data JPA를 사용해서 데이터베이스에 접근하도록하고 동적으로 데이터가 변경되어야 하는 것들 (검색.. )과 관리자 화면에서의 통계와 기능들은 동적 쿼리를 사용할 수 있도록 QueryDSL을 도입.
    • Spring Security / JWT / OAuth 2.0 Client - 프로젝트에 사이트 로그인과 소셜 로그인 기능을 모두 포함하기 위해서 Spring Security와 OAuth 2.0 Client를 사용하여 관리하기 위해 도입. 세션을 쓰지 않고 무상태 기반의 JWT를 사용하여 이후 서비스 확장성을 고려하고 스케일 아웃 시 영향이 적은 JWT를 도입
    • Spring Data Redis - JWT를 도입하면서 Refresh Token과 Access Token을 따로 두는 방식을 채택했었는데 이를 관계형 데이터 베이스를 저장하지 않고 자주 지워지고 갱신되어야 했기 때문에 메모리 기반의 저장소를 채택하여 매번 쿼리를 날리지 않고 빠르게 저장할 수 있도록 구성.
    • Spring Cloud OpenFeign - 선언적인 클라이언트를 통해서 서버 단에서 다른 서버에게 요청을 보내서 응답을 받아와서 활용할 수 있도록 도와줌. 기존의 Spring Data JPA와 사용 방식이 비슷하여 새로 사용해보는 기술이라 하더라도 러닝커브가 낮다고 판단되어서 외부 API 호출 시에 적용
  • Database
    • MySQL 8.1.0

개발 기여

이번 프로젝트 기간 동안은 다음과 같은 작업을 맡아서 진행했습니다.

  • Kakao Map API와 자바스크립트의 내장 API인 Geolocation API를 사용하여 사용자의 현재 접속 위치 정보를 호출 할 수 있는 기능 
    • 기존의 Geolocation API는 비동기로 작동하고, 동작속도가 느리기 때문에 사용자 정보를 받아오는 시간이 상당히 느렸습니다. 저희 서비스의 경우 Geolocation API에서 받은 위도와 경도를 통해서 카카오 지도 API로 요청을 보내 그 요청이 실제 주소로 변경해올 수 있도록 하였습니다. 해당 정보를 받아오지 못하면 서비스를 사용할 수 없도록 설계 되어 있어서 사용자 경험을 위해서 해당 정보를 캐싱하거나 어딘가에 저장하여 방법을 찾아야 했습니다. 이에 따라서 첫번째로 Geolocation API의 정확성을 낮추는 대신 좌표를 호출하는 속도를 개선하고 클라이언트에 10분동안 캐싱을 할 수 있도록 설정을 바꾸었고 이를 통해 사용자가 매번 접속을 할 때마다 가져오는 것이 아닌 호출 후 캐싱을 통해서 로그인 하고 있는 동안에 지속적으로 해당 위치 정보를 사용할 수 있도록 하였습니다. 물론 이 경우는 서버단에서 해결하지는 못했지만 이후 사용자가 많아진다면 클라이언트 서버에서 부담이 갈 수도 있다는 생각이 들어 이후에 레디스와 같은 메모리 기반의 저장소에 캐싱을 하는 방식으로 리팩토링 할 예정입니다.
  • OAuth 2.0 Client를 이용한 카카오 로그인 기능 도입 
    • 이번 프로젝트를 설계하면서 폼 로그인과 소셜 로그인을 모두 도입하기로 결정하면서 폼 로그인 부분은 다른 팀원이 도맡아서 진행해주었고 제가 이전에 현재 위치 정보를 받아오고 사용하는 과정에서 카카오 API키를 가지고 있었기 때문에 카카오 소셜 로그인 기능을 도입하는 부분을 맡아서 진행했었습니다. 소셜 로그인을 구현하면서 회원들이 하나의 이메일로 여러 소셜 계정을 사용하는 경우가 많고 이를 고려해서 소셜 로그인과 기존 사이트 로그인의 회원 테이블을 같이 관리하면서 아쉬운 점이 있었습니다. 이 때 서비스에서는 소셜로 가입한 회원을 회원 테이블 하나의 컬럼을 통해서 관리 하고 있었는데 이와 같은 경우 해당 유저가 그 이메일을 통해서 로그인 할때 다른 경로의 로그인 (소셜회원이지만 기존 사이트 로그인을 통해서 로그인을 한다던지..) 와 같은 방식에서 이미 회원 가입이 되어있지만 경로가 달라 로그인이 안되는 형태였습니다. 이와 같은 경우 서비스의 확장성에 있어서 제한 적이라고 판단 되었습니다. 추후에 다른 경로의 소셜 로그인이 생긴다면 컬럼에 하나의 새로운 타입 (구글, 메타, ...)등을 추가하면 되지만 사용자 입장에서는 하나의 이메일이 있다면 어떤 경로로 회원가입 했냐와는 관계없이 항상 그 이메일로 접근을 원할 것 같다는 생각이 들었습니다. 이에 따라서 추후에 어떤 경로로 접근하던 로그인할 수 있도록 소셜 로그인 테이블을 따로 두는 방식으로 변경해볼 예정입니다.
  • Swagger를 통한 API 명세 세부화
    • 프로젝트를 진행하면서 팀원들과 API 명세를 대략적이라도 작성하고 프로젝트를 진행하자고 계획하였습니다. 하지만 프로젝트 일정이 빠듯했기에 처음 계획과는 다르게 명세를 API를 개발한 이후에 만들 수 있었습니다. 이에 따라 여러 가지 경우의 수를 고려 하였었는데, 이 때 도입을 고려한 기술이 Spring Rest Docs 와 Swagger 였습니다. 이들은 둘다 API 명세 라이브러리로서 각각의 장단점을 가지고 있습니다. Spring Rest Docs는 Presentation Layer (Controller) 계층에 대한 테스트를 작성해야하고 이것이 통과되야지만 문서화를 할 수 있어서 번거롭지만 그만큼 테스트 작성을 강제하므로 테스트를 작성할 수 있고, 타입에 대한 테스트를 통과해야 하기 때문에 관련된 정보를 따로 제공하지 않아도 되서 편리합니다. Swagger와 같은 경우 세부 설정을 하지 않아도 페이지를 만들어주고 해당 API 호출에 대한 테스트를 swagger 페이지에서 할 수 있지만 컨트롤러 단의 코드가 너무 많은 어노테이션으로 인해 보기 힘들어질 수 도 있습니다. 두 가지 경우에서 일단 팀원들이 전반적으로 테스트에 대한 경험이 낮았고 러닝커브가 낮은 스웨거를 채택하여 명세를 진행하였습니다. 이에 따라서 모든 요청과 응답 DTO 및 API 경로에 대한 문서화를 대략 80%이상 진행할 수 있었습니다.

'Kernel360 > 프로젝트' 카테고리의 다른 글

[Kernel360] Hackathon : ministory ~ Orury  (0) 2023.11.01
[Kernel360] Boot-Up : TwoStar  (1) 2023.11.01