패스트캠퍼스 X 야놀자: 백엔드 개발 부트캠프

패스트캠퍼스X야놀자: 백엔드 개발 부트캠프 - Toy#2 여행 여정을 기록, 관리하는 서비스

이-프 2023. 11. 7. 02:27

서비스 개요

서비스 목적 및 목표

목적

여행 여정을 기록과 관리하는 SNS 서비스를 만든다.

목표

  1. 여행의 여정 정보를 기록하고 조회하는 Spring Boot 기반 RESTful API 를 개발한다.
  1. 진행한 여행, 여정 정보를 조회, 등록 수정하기 위한 ERD 설계 및 개발한다.
  1. 여행과 여정 정보를 조회, 등록, 수정하기 위한 RESTful API 설계/개발한다.
  1. 진행한 여행, 여정 정보를 조회, 등록 수정 후 저장한다.
  1. 일정 정보에 위치 정보를 확인 및 추가하는 공통 유틸리티 클래스 제공한다.

서비스 설계

패키지 구조

✅ DDD 구조 (Domain Driven Design)

패키지구조 설계는 대표적으로 ‘계층형’ 구조와 ‘도메인형’ 구조가 있다. 그 중 도메인형 구조는 각각의 도메인 별로 패키지 분리가 가능하여 도메인 별 관리가 직관적이다. 도메인 별로 의존하는 코드가 없도록 설계가 되었기 때문에 추후에 기획이 추가되더라도 코드를 재활용할 수 있기에 domain형 구조를 선택했다. 실제로, 이전 Toy#1프로젝트에서도 DDD 구조를 선택했기에 Toy#2 프로젝트에서 기획을 추가하여도 코드를 재사용할 수 있었다.

✅ MVC 구조

Domain 형 구조를 토대로 Model을 담당하는 dto, 입출력을 담당하는 View, service를 담당하는 Main로 MVC구조를 표현했다. 이번 프로젝트에서는 Web과 통신하지 않기에 Controller를 따로 구현하지는 않았지만, 이후 Spring framework를 사용시 Controller를 구성할 계획이다.


요구사항 분석

  1. 회원은 여러 여행 기록과, 여정 기록을 저장할 수 있습니다.
  1. 회원은 여행기록을 확인 후 상세한 여정 기록을 추가 및 조회할 수 있습니다.
  1. 여행정보와 여정정보를 각각 수정할 수 있습니다.
  1. 여행 정보는 여러 여정 정보로 구성됩니다. (여행 : 여정 = 1 : n)
  1. 여행 정보에는 다음 정보가 필수 항목으로 포함되어야 합니다.
    1. [여행]의 이름, 일정(출발 날짜, 도착 날짜), 국내/외 여부
  1. 여정 정보에는 다음 항목으로 분류됩니다.
    1. 이동 (이동 수단, 출발지(장소명), 도착지(장소명), 출발 일시, 도착 일시)
    1. 숙박 (숙소명, 체크인 일시, 체크아웃 일시)
    1. 체류 (장소명, 도착 일시, 출발 일시)
  1. 여행 정보 및 특정 여행 정보의 여정 목록은 데이터베이스에 저장됩니다.
  1. 일시정보와 위치정보가 있으며, 일시에 대한 공통 유틸리티 클래스를 생성하여 활용합니다.


ERD 설계

  1. Single Table 전략을 사용하는 case

    SINGLE_TABLE 전략을 사용하여 Itinerary를 Accommodation, Transportation, Visit이 상속받는 ERD

    🚀 ERD 설계를 하며 공부한 JPA 상속관계 매핑은 자체적으로 포스팅했다.

    🔗 https://for-if.tistory.com/51

서비스 기능

기능설명


입출력화면

이번 Toy #2 Project에서는 Spring REST Docs를 도입하여 API를 문서화했다.

입출력화면은 아래 RES Docs 링크를 통해 확인할 수 있다.

https://www.notion.so/dev-if/9-Toy-Project-2-Spring-REST-Docs-d052850bde2542cc8ecb5e2f5150a31f

개발을 진행하면서 Postman을 통해 API test를 진행했다. 담당한 여정 조회 API postman test는 다음과 같다.


역할 분담

⚡ 팀원들의 이름은 비공개처리했다.

내가 맡은 업무는 총 3가지였다.

  • 여정 조회 API
  • 여정 삭제 API

팀 협업

  • 애자일 방법 선택
    • 계획 → 설계 → 개발 → 테스트 → 피드백 순으로 프로젝트를 시작한 후 끊임없이 개선에 노력했다.
    • 프로젝트 첫째 날에 전반적인 계획 및 설계를 마무리하고, 이후로 개발을 시작하면서 부족한 계획 및 설계를 보완하면서 진행했다.
    • 중도에 DB 설계를 바꾸게 되면서 요구사항을 바꾸어 유연하게 개발을 했다.
  • CI 전략
    • Github Action을 통한 CI 전략을 추가하여 안정적으로 PR을 진행했다.
    • 결과적으로 develop 브랜치에 안전한 코드들로 유지할 수 있었다.
  • Git-Flow 전략
    • main, develop, feature 등 git flow 전략을 사용하여 협업을 진행했다.
  • 고정적인 회의 시간
    • 매일 오후 2시, 오후 5시에 회의를 진행했다.
    • 오후 2시 : 하루 동안 개발한 상황 공유
    • 오후 5시 : 2시 이후 개발을 하면서 생긴 질문사항 등을 공유
    • 추가적으로 회의가 필요하다면 시간을 내어 회의를 진행했다.

개인공부 정리

https://github.com/FC-Toy-Project-9/Toy_Project2

Trouble Shooting 🚀

구체적인 Trouble Shooting은 자체 포스팅에 구체적으로 작성해뒀다.

1. DB 설계 수정

⚠️ 문제 상황

프로젝트를 시작하면서 팀원들과 협의 하에 Entity를 구조화했다. 기존에는 DB를 설계하며 JPA 상속 관계 매핑 전략 중 JOINED 전략을 사용하기로 했다. 하지만, 실제 개발을 진행하며 파악하지 못했던 JPA N+1문제가 발생했다.

✅ 해결 방안

JPA에 대해 집중적으로 공부해보기로 했다. 그 과정 속에서 JPA N+1 문제를 해결할 수 있는 fetch join에 대해 알게됐다. 하지만 이 fetch join 보다 프로젝트의 규모를 생각하여 SINGLE_TABLE 전략을 선택했다.

🔗 JPA 상속 관계 매핑 : https://for-if.tistory.com/51

2. JPA 연동

⚠️ 문제 상황

프로젝트 실행시, 자동으로 해당 class의 이름을 갖는 DB table을 생성하기 위해 SpringBoot + JPA(Hibernate)를 사용했다. 하지만, entityManagerFactory bean을 생성할 수 없다는 에러가 났다.

✅ 해결 방안

MariaDB Dialect 설정을 변경해주고, createDatabaseIfNotExist=true 추가하여 연동 문제를 해결했다.

🔗 MariaDB + JPA 연동 : https://for-if.tistory.com/49

3. 팀 협업 (스케줄링)

⚠️ 문제 상황

각자 맡은 업무를 목요일(개발 시작 3일 후)까지 완료하여 최종 코드를 merge하여 main 브랜치에 push하기로 계획했다. 하지만, 팀원 중 한 분의 개인적인 일로 인해 기간 마감일까지 완료하지 못했고 해당 팀원의 코드와 같은 domain에서 작업해야하는 내가 맡은 개발 업무의 테스트까지 미뤄지게 됐다.

✅ 해결 방안

일요일 (개발 시작 7일 후)까지 최종 제출을 해야했기에 무기한 시간을 드릴 수 없었다. 해당 팀원과 회의 후, 팀장님이 해당 팀원의 업무를 나눠서 기능 구현을 하게 됐다. 팀장님이 책임감있게 프로젝트를 이끌어주신 덕분에 결과적으로는 제출 기간 내에 마무리할 수 있었다. 팀장님이 개발을 추가적으로 하시는 동안, 같은 domain에서 작업하는 내 코드와 충돌이 나지 않도록 최대한 내가 맡은 코드를 testing하며 에러가 없는지 확인했다. 또한 기획서를 맡아서 주도적으로 작성하며 팀원들과 협업을 진행했다.

프로젝트를 마무리하며 .. 🐣

Spring Boot를 사용한 첫번째 프로젝트이다. 첫번째 프로젝트보다 Spring Boot MVC구조를 더 잘 이해하여 개발할 수 있었다. 하지만 DB설계를 변동하면서 JPA는 부족함을 느껴 프로젝트를 마무리함과 동시에 JPA 공부를 추가적으로 진행할 계획이다.

앞으로 Toy#3 프로젝트에서는 Security, JWT 등 추가적인 기술을 접목한다. Toy#1에서 기술들을 추가하며 프로젝트가 본격적으로 성장하면서 나 또한 성장하는 계기가 된 것 같다.

이번 프로젝트를 하면서 백엔드 개발자들 간의 협업 방법에 대해 진지하게 고민해볼 수 있었다. 커뮤니케이션과 더불어 CI전략, GitFlow전략을 활용한 코드 update 등 더 넓은 시각을 갖게 된것 같다. 특히, 예외처리와 TestCode에 대한 중요성을 뼈저리게 느꼈다. HTTP200을 띄우는 코드는 쉽지만, 소비자의 입장에서 발생할 수 있는 모든 예외들을 생각해서 대비하는 코드를 작성하는게 낯설었다. 앞으로 프로젝트를 하면서 예외처리에 대한 고민을 더 심층적으로 해봐야겠다.


Uploaded by N2T