[프리온보딩 백엔드] 카닥 기업 과제 회고👏

Sewon·2021년 12월 5일
0

[Pre Onboarding] BE

목록 보기
3/4
post-thumbnail

이번 카닥 기업 과제에서 가장 신경썼던 부분은 주어진 조건에 알맞은 사용자, 타이어에 대한 모델링 방식과 타이어 정보 저장 저장 순서였다.

✔️모델링 방식

#방안1 - 사용자와 타이어 1:N 관계

장점 : 사용자가 소유한 타이어 정보 조회 API 제공 시 빠름
단점 : 생성된 타이어 객체는 한 명의 사용자에게만 해당하므로 동일한 타이어 정보 값을 가진 타이어 객체가 많아질 수 있음, 타이어 정보 조회 시에만 유용함(확장성 X)

#방안2 - 사용자와 타이어 N:M 관계 (채택!)

장점 : 중복된 값(폭, 편평비, 휠사이즈)을 가지는 타이어 객체가 생성되지 않음, 확장성이 좋음(ex.가장 많이 소유한 타이어의 종류 등 다양한 API 제공 가능)

채택 이유) 중복된 값(폭, 편평비, 휠사이즈)을 가진다면 동일한 타이어라고 가정하기로 하였고, 추후 다양한 API를 추가하여 발전시킬 수 있어서 해당 모델링 방식으로 구현하였다.

#방안3 - 사용자와 자동차 N:M 관계 & 자동차 필드에 타이어가 들어감

장점 : 사용자가 소유한 자동차 정보도 저장 가능함
단점 : 해당 프로젝트에서 제공해야할 사용자 소유 타이어 정보 조회시 복잡함

✔️타이어 정보 저장 순서

상황

해당 프로젝트에서 구현해야할 기능중 사용자가 소유한 타이어 정보 저장 API가 있었다.
해당 API의 요구사항은 다음과 같았다.

  • 자동차 차종 ID(trimID)를 이용하여 사용자가 소유한 자동차 정보를 저장한다.
  • 한 번에 최대 5명까지의 사용자에 대한 요청을 받을 수 있도록 해야한다. 즉 사용자 정보와 trimId 5쌍을 요청데이터로 하여금 API를 호출할 수 있다는 의미이다.
/* Request Body 예제 */
[
  {
    "id": "candycandy",
    "trimId": 5000
  },
  {
    "id": "mylovewolkswagen",
    "trimId": 9000
  },
  {
    "id": "bmwwow",
    "trimId": 11000
  },
  {
    "id": "dreamcar",
    "trimId": 15000
  }
]

요구사항은 간단했지만, 직접 코드로 구현하기 위해서는 세부 조건을 명확히 정하는 것이 중요하다고 생각하여 관련 세부 조건을 자체적으로 정하였다.

➡️로직 구현을 위한 세부 조건
  • 해당 API 호출 가능한 사람
    • 인증된 사용자만 (다른 사용자가 소유한 타이어 정보도 저장이 가능함)
  • 최대 5개의 요청 데이터에 대해 1개라도 올바르지 않은 데이터가 있을 때의 처리
    • 모든 요청 데이터가 올바른 경우에만(예외를 발생시키지 않는 경우) 정상 요청으로 판단
    • 1개라도 올바르지 않은 데이터(예외를 발생시키는 경우)가 있는 경우 Exception 반환
  • 올바르지 않은 데이터(예외 발생)의 조건
    • 요청 데이터의 개수가 1~5개가 아닌 경우 (400 Bad Request)
    • 해당 id 값을 가진 사용자가 존재하지 않는 경우 (400 Not Found)
    • 자동차 정보 조회 외부 API 응답 상태코드가 200이 아닌 경우 (400 Bad Request)
    • 자동차 정보 조회 외부 API 응답 상태코드가 200이지만, 응답의 spec → driving → frontTire/rearTire 에서 타이어 정보를 찾을 수 없는 경우 (400 Bad Request)
  • 올바른 타이어 정보 포맷인지 확인 과정
    • 공백(\t, \n, \x0B, \f, \r) 제거
    • {차량종류}{폭}/{편평비}R{휠사이즈} 패턴에 맞는지 확인
    • 올바른 포맷인 경우
      frontTire, rearTire 중 올바른 포맷의 타이어만 저장
      frontTire와 rearTire가 동일한 타이어 정보인 경우 Tire 객체 1개 생성, 사용자 소유 타이어 1개 생성
    • 올바르지 않은 포맷인 경우
      예외 처리는 되지 않고 사용자 소유 타이어 정보가 저장되지 않음
      (외부 API의 응답값의 포맷이 달라서 발생한 경우이므로 예외라고 보지 않았음)

위와 같은 세부 사항을 정하였고, 핵심 기능인 사용자 소유 타이어 정보 저장 순서에 대한 방안을 생각해보았다.

#방안1 - 채택!

  1. (사용자id, trimID)를 한 쌍으로 데이터 유효성 검사 수행
    사용자 정보 존재 확인
    trimID에 대한 외부 API 응답 코드 & 응답에서 타이어 정보 찾을 수 있는지 확인
    올바른 타이어 포맷인 경우 타이어 정보를 데이터베이스로부터 가져오거나 새로 생성
  2. 1의 검사 통과했고, 해당 (사용자, 타이어) 정보가 데이터베이스에 아직 없는 경우에 UserTire 객체 생성하여 List<>에 저장해둠
  3. 모든 요청 값에 대해 1,2 과정 수행 후 List<>에 있는 UserTire 객체를 데이터베이스에 저장

장점 및 채택이유

  • 올바르지 않은 데이터가 존재해 중간에 예외가 발생한 경우 데이터베이스 rollback을 수행하지 않아도 됨
  • 새로운 타이어 정보는 데이터베이스에 무조건 저장됨(타이어 정보는 요청 시 마다 새로운 값일 경우 데이터베이스에 새로 생성해둬도 문제가 없음)

단점

  • 들어온 값과 List에 대한 조회를 해야 함

#방안2

(사용자id, trimID) 조회 후 올바른 데이터인 경우 각각 중개 테이블 객체 생성 → 중간에 틀린 데이터가 존재한다면 데이터베이스 Rollback

장점

  • 모두 올바른 데이터인 경우 빠른 처리 가능

단점

  • 데이터베이스 Rollback 해야 함(중개 테이블에 대해)
  • 타이어의 경우에는 우선 생성되면 좋음(굳이 rollback 필요X) → 해당 방식에서는 예외 발생하는 경우 rollback 하기 때문에 생성된 타이어도 rollback 됨

➕상황에 따른 구체적인 Response Code 정해두기

이전에 8퍼센트 기업 팀 과제를 수행하며 구체적인 Response Code를 작성해두었던 것이 도움이 되어 이번 프로젝트에서도 구체적으로 작성해두기로 하였다.
따라서 각 API 별로 발생 가능한 예외 상황을 고려하여 처리 방식을 미리 정해두고, 각 상황에 따른 Response Code를 미리 정해두어 효율적으로 코드를 작성하였다.

➡️API 별 Response Code 확인

profile
for develop ☁️

0개의 댓글