Dev/Django

WebSite(wiselyshave) Clone Project - Part.2 Data Modeling & End Point Refactoring

sincerely10 2020. 8. 2. 20:59
반응형

안녕하세요. 이 포스트는 시리즈로 구성되어있습니다. 

<1차 Clone Project 회고>
WebSite(wiselyshave) Clone Project - Part1.시작&데이터모델링
WebSite(wiselyshave) Clone Project - Part.2 Data Modeling & End Point Refactoring
WebSite(wiselyshave) Clone Project - Part.3 views.py Refactorin
WebSite(wiselyshave) Clone Project - Part.4 후기

지난번 wiselyshave.com 클론 프로젝트의 모델링을 소개했습니다.
제 모델링이 틀렸다까지는 아니지만, 프로젝트가 끝난 지금 돌이켜보니 효과적이지 못 했던 것 같습니다. 적어도 이번 클론 프로젝트에서만은 확실하게 느꼈습니다.

모델링이 매끄럽지 못한 데서 오는 피해는 한두 가지가 아녔습니다. 단순히 데이터를 저장할 때 복잡하고 테이블이 많아지는 것을 떠나서(물론 정규화에 의해 테이블이 많을 수도 있지만) Hard Coding(하드코딩)을 하게 되는 것이 문제였습니다.

지금부터 하나씩 복기 해보도록 하겠습니다.

1. 다시 작성해보는 데이터 모델링

지난번 포스팅에서 모델링을 자세하게 풀어썼는데 이번에도 변경된 부분에 대해 하나씩 작성해보겠습니다.

추가된 테이블은 razor_colors라는 테이블로 프론트 엔드단의 요구로 면도기 구매 시 우측에 팝업으로 뜨는 정보를 저장해서 불러와줍니다. 이후에도 지속적으로 나오겠지만, 이 모델링의 문제점은 세 가지의 다른 구매 옵션(Color, Size, SkinType)에 대한 대응을 products와 Join 하여 해결했다는 것입니다. 그렇기 때문에 장바구니에 저장된 아이템을 불러올 때나 Bulk Item 구매(no option, Size&SkinType)에 대해서 각각을 별도로 매핑해줘야 하는 것이죠.

products_sizes, products_colors, blade_products 이 3개의 테이블이 products와 각 속성을 참조하는 테이블입니다. 이 정도면 데이터를 구성하는데 문제가 없겠다 생각했지만, 말씀드린 것처럼 각각을 매핑해주기 때문에 비효과적이었습니다.

그래서 프로젝트를 확인해주시는 멘토님께서 API를 작성하는 views.py를 보시고 데이터 모델을 추천해주셨습니다. 그 모델링에 대해 지금부터 소개하겠습니다.

개선한 데이터 모델링

가장 크게 변경된 부분은 option이라는 테이블이 생긴 것입니다. 이 option 테이블이 세 가지 속성(Color, Size, SkinType)의 id 값을 참조하고 있습니다. 그리고 product(제품 테이블)과 option 테이블이 ManyToMany 관계에 있기 때문에 products_options라는 테이블이 만들어집니다. 이 테이블이 가격정보를 담고 있습니다.

즉, 3개의 구매방식(색상 고르는 제품, 아무것도 선택하지 않는 면도날, 사이즈를 선택하는 피부제품(skintype은 종속시킴))의 테이블(products_colors, blade_products, products_sizes)로 나뉘던 테이블을 products_options라는 테이블로 단일화된 것입니다. 이렇게 만들면 편의상 size에 종속시켰던 skintype 또한, 개별로 둘 수 있어 제품 변경에 대한 대응이 가능합니다.

이는 Order 테이블과 상품 테이블(products_options)의 ManyToMany로 만들어진 order_items 테이블에도 적용됩니다. 기존에는 3개의 테이블을 참조했다면 이제 products_options만 참조하면 됩니다.

추가로 리팩토링 하면서 요구사항에 의해 만들었던 razor_colors라는 테이블을 colors에 종속시켰습니다. 색상 참조는 면도기만 하기 때문이죠. 만약 다른 상품도 색상을 고른다면 분리시켜야 할 것입니다. 그리고 장바구니 담길 때 보이는 이미지 테이블인 order_images 또한, products_options에 종속시켰습니다. 장바구니 이미지가 여러 장이 아닌 한 장만 갖고 있기 때문이죠.

이런 방법으로 테이블을 4개를 줄일 수 있었습니다.

그리고 중요한 정보를 언급하지 않은 것이 있습니다. 위의 리팩토링 모델링을 보면서 products(제품) 테이블과 각 속성 테이블의 ManyToMany 관계로 생성된 3개의 (products_colors,blade_products,products_sizes) 테이블은 왜 생성하지 않았는지 의문일 수도 있을 것입니다. 정확히는 이러한 과정을 반정규화(Denormallization)이라고 합니다. 중복되거나 생성되는 데이터에 대해서는 정규화를 하지 않는 것입니다.

2. End Point Refactoring

우선 Postman으로 생성한 API Doc을 첨부 합니다.

https://documenter.getpostman.com/view/11646894/T1Dv9EwL

user Appr과 마지막 Review url은 제가 작성한 것이 아니므로 별도의 언급은 하지 않겠습니다.
프론트엔드 지식이 미약한 제가 가장 크게 착각한 것은 React와 같은 app에서 온 POST API에 대해서 무조건 갱신된 Response를 보내줘야 한다고 생각한 것입니다. 
이 부분 때문에 저와 함께 하는 프론트엔드 개발자도 고생이 있었을 것입니다.

예를 들자면, 장바구니에 면도기 제품을 담으면 색상 선택 bar가 사라지고, 장바구니 리스트가 뜹니다. 저는 이 API를 보여주는데 있어 댓글을 작성할 때 새로운 댓글 목록을 Response 받아 보여주듯이 항상 받은 Response로만 해결해주는 줄 알았습니다.

그러나 추가되고 삭제될 때는 그 Request만 처리하고 새로운 창으로 전환할 때, 리스트를 조회하는 방식이 제가 하는 클론 프로젝트에 적용되어야 했습니다. 아마 Response로만 처리하려 했으면 비동기 방식(asynchronous)으로 처리했어야 했을 것입니다.

추가로는 '/product/color-detail' 라는 색상 선택 옵션과 면도기 사진을 확인하는 API가 있는데 이 별도의 API를 제품 정보를 Response 해주는 API에 같이 정보를 담을 수 있다고 생각했습니다. 미리 보내 놓고 이벤트에 맞춰 받은 정보를 출력하는 형태로요.

Restful 하게 작성한다는 것이 아직 온전히 감을 잡기는 어렵습니다. 프론트엔드의 지식도 어느 정도는 갖춰야 한다는 것을 다시 한번 절감하였습니다.

반응형