/ PROJECT, CARDOC, WECODE, WANTED

백엔드 프리온보딩 4주차 첫번째 프로젝트 회고


원티드 4주차 카닥 기업과제


진행기간

21.11.23 ~ 21.11.26


구현해야 하는 기능

  • 사용자 생성 API(회원가입/로그인)

  • 사용자가 소유한 타이어 정보를 저장하는 API

  • 사용자가 소유한 타이어 정보 조회 API


나의 역할

  • 사용자 생성 API(회원가입/로그인)
  • 사용자가 소유한 타이어 정보를 저장하는 API
  • 사용자가 소유한 타이어 정보 조회 API
  • Unit Test 코드 작성
  • README.md 작성
  • EC2 배포

프로젝트 회고

프리온보딩의 마지막 프로젝트였다. 벌써 시간이 이렇게 지났다니.. 😥 이번 프로젝트는 카닥이라는 기업의 과제였다. 개인 과제로 프로젝트를 마무리 하게 되었다
카닥에서는 타이어 정보 API를 제공해주었고 이 API에서 제공해주는 데이터를 가지고 타이어의 정보를 데이터베이스에 저장해야 하는 과제였다. 이 부분만 제외하면 지금까지 해왔던 과제들과 크게 다르지 않을 것 같았다.

역시나 시작은 모델링 설계,, 항상 팀원들과 함께 진행하다 혼자 하려니 허전했다.. ㅎㅎㅎ 주어진 타이어 정보 API에는 자동차에 대한 정보들이 굉장히 세세하게 나와있었다. 어디까지 저장하라는 조건이 없었기에 스스로 생각해서 데이터 정보를 어디까지 저장할지 결정해야 했다.

나는 해당과제는 유저가 소유한 자동차의 타이어 정보를 저장하고 조회하는 과제인만큼 타이어 정보에 초점을 맞추기로 했다.

requests의 사용

타이어 정보를 저장하는 body request는 아래와 같이 최대 5명의 유저들의 정보에 대한 요청을 할 수 있다. trimId가 https://dev.mycar.cardoc.co.kr/v1/trim/{id} 의 url에 파라미터로 담겨 해당되는 자동차의 정보가 출력된다. 이때 필요한 데이터를 가져오기 위해서 requests를 사용했다.

[
    {
        "id": "test1",
        "trimId": 72
    },
    {
        "id": "test2",
        "trimId": 7000
    },
        {
        "id": "test3",
        "trimId": 30
    },
        {
        "id": "test4",
        "trimId": 9000
    }
        {
        "id": "test5",
        "trimId": 12000
    }
]


과제 조건에 써져있는 것처럼 spec → driving → frontTire/rearTire -> 타이어 정보 frontTire와 rearTire의 값인 value를 {폭}/{편평비}R{18}의 포맷에 맞게 각각 나누어 폭, 편평비, 휠사이즈로 각각 데이터베이스에 저장해주어야 했다

즉 자동차마다 각각의 자동차 스팩을 가지고 있었고 스팩 중 하나가 자동차 타이어에 대한 정보였다. 그래서 나는 자동차의 기본정보를 가지고 있는 테이블과 자동차의 스펙을 스펙 테이블로 나누어 1:1로 연결해주었다. 그리고 스펙 테이블에서는 타이어의 스펙이 같은 자동차가 존재할거라고 생각했기 때문에 타이어 테이블과 스펙 테이블을 1:n으로 연결시켜주었다.

설계 과정에서 가장 고민이였던게 바로 타이어가 앞/뒤 타이어로 정보가 나뉘는데 각각의 테이블로 나누어 저장할지 하나의 타이어 테이블을 만들어 저장할지 고민이였다. 고민 끝에 해당 과제는 타이어의 정보가 중요했기에 앞 타이어와 뒤 타이어에 대한 테이블을 나누어 설계하기로 결정했다.

  • requests이용한 타이어 정보 가져오기
car_info   = requests.get(f"https://dev.mycar.cardoc.co.kr/v1/trim/{trim_id}").json()
front_tire = re.split("[P/R]",car_info.get("spec")["driving"]["frontTire"]["value"].replace(" ", ""))
rear_tire  = re.split("[P/R]", car_info.get("spec")["driving"]["rearTire"]["value"].replace(" ", ""))

info_dic = {
    "trim_id"   : trim_id,
    "car_brand" : car_info.get("brandName", None),
    "year_type" : car_info.get("yearType", None),
    "car_name"  : car_info.get("submodelGroupName", None),
    "front_tire": front_tire,
    "rear_tire" : rear_tire
}

타이어 정보를 가져올때 과제에 정해진 타이어 정보 포맷이 있었다. 포맷이 지켜지지 않으면 데이터베이스에 저장할 수 없었다. 그래서 정규표현식을 이용해 정해진 포맷이 아닐 경우 빈 리스트를 가져오게 구현했다. 그리고 빈 리스트일 경우 except문으로 빠져나가 unsaved_tire_list.append(data["id"]) 의 로직으로 인해 저장되지 않은 리스트에 해당 유저가 담긴다

view에서 for문을 돌면서 중간에 에러가 나도 그 다음부터는 정상적으로 저장되게 구현하고 싶었기 때문에 에러가 난 유저의 자동차 정보부터 스펙 정보 ~ 타이어 정보까지 전부 저장되지 않게 구현했다 (여기서 원자성을 고려했다 !)


진행한 소감

벌써 마지막 프로젝트라니 .. 할 때는 너무 힘들었는데 마지막이라고 하니까 뭔가 아쉽다.. 처음 만난 팀원들과 첫 날부터 쉬지 않고 지금까지 함께 달려왔고 완주했다는 것에 만족스럽다. 다들 열심히 하는 모습에 자극도 많이 받고 배운점도 너무 많은 것 같다.. :-) 무엇보다 함께하니 절대 못할 것 같은 것도 해내게 되는 과정이 나름 짜릿하다.. 물론 초반에는 밤도 밥 먹듯이 새고.. (진짜 아예 새버렸다.. 저녁 8시에 시작했는데 다음날 7시 넘어서 끝났다.. 😂😂😂)

그럼에도 누구하나 포기하지 않고 탓하지 않고 열심히 하려는 팀원들에게 고마웠다. 물론 어려웠던 상황도 꽤 있었지만 우리만의 나름의 소통(?)을 통해서 자기자신을 다시 바라보고 고치려고 하는 모습과 배려하려는 모습이 보였기 때문에 웃으며 이겨낼 수 있었다. ^^

왜 협업이 중요한지에 대해 말하는건 입이 아플 정도다. 혼자서 잘한다고 절대 멋진 결과물을 만들어 낼 수 없다.. 적극적인 커뮤니케이션이 우리 팀이 처음부터 끝까지 포기하지 않고 다함께 프로젝트를 마무리 할 수 있었던 이유였던 것 같다

난 덕분에 git rebase와 squash에 익숙해질 수 있었다.. :-) 그리고 적극적인 코드리뷰 덕분에 코드를 바라보는 시각을 넓힐 수 있었다.. (코드리뷰 시간만큼은 마치 사수와 함께하는 기분이 들었다..^-^)

열심히 해준 팀원들도 고마웠고 나 자신 또한 자랑스러웠다 후후