[회고] 1차 프로젝트를 마치며.

박광수·2022년 4월 10일
0

프로젝트 정보

  • 팀명 : 솥지마요 (한솥+참치마요)
  • 참여 인원 : FE 4명(홍두현, 박경서, 이근휘, 김정수), BE 2명(박광수, 최창환)
  • 내용 : 한솥 홈페이지 클론코딩
  • 기간 : 3/28 ~ 4/8
  • Github : https://github.com/wecode-bootcamp-korea/31-1st-Dont-SOT-backend
  • 사용 기술 (백엔드) : Python, Django, Git&Github
  • 일정 관리 및 기록 : Notion, Trello, Slack
  • 구현 범위 (백엔드) : 메인페이지 API, 상품 목록 및 상세페이지 API, 회원가입&로그인 API, 장바구니 API

프로젝트 기록

1 . Modeling

모델링을 쉽게 생각하고 접근했었다. '왜 이틀~사흘이나 모델링에 투자해야 된다고 하는 걸까?'
db구조를 모델링 하는 것이 중요한 이유는, db의 구조를 도중에 업데이트하거나 추가 또는 삭제하는 것이 번거롭기도 하고 위험부담이 있기 때문이다.
발사각이 0.1도라도 엇나가면 궤도가 완전 달라지는 우주선처럼, 프로젝트 초기의 방향설정을 얼마나 바람직하게 하느냐에 따라 뒤늦게 모델링 수정할 때의 수고로움을 덜 수 있을 것이다.
결국 우리 프로젝트도 중간에 모델링을 뒤집게 되었다. 곱빼기라는 옵션 구현을 어떤 구조로 구현할 것인지 방법을 정확히 했어야 했다.

  • 1차 모델링
  • 2차 모델링

결국 2차 모델링 그대로 가지 못했다. 주문기능(order)는 시간 상의 이유로 구현하지 못했고 옵션의 단순화와 그로인한 불필요한 테이블 삭제 등의 이유이다.

  • 가장 인상 깊었던 모델링 (곱빼기 상품을 어떻게 관리할 것인가)
class Product(models.Model): 
    name             = models.CharField(max_length = 30, null = True)
    price            = models.DecimalField(max_digits = 10, decimal_places = 2)
    description      = models.TextField()
    calory           = models.DecimalField(max_digits = 10, decimal_places = 2, null = True)
    category         = models.ForeignKey("Category", on_delete = models.SET_NULL, null = True)
    relative_product = models.ForeignKey("self", on_delete=models.CASCADE, null=True)
    sales            = models.IntegerField(default = 0)

한솥 메뉴에는 각 상품마다 곱빼기추가, 김 추가 등의 옵션을 구비해놓았다. 우리는 그 중에 곱빼기만 구현하기로 하였고 relative_product column이 그와 관련있다. 예를 들어 pk가 1인 제품이 치킨마요(보통) 이고 pk가 2인 제품이 치킨마요(곱빼기)라면 2번의 relative_product column에서 1번을 참조하기로 한 것. 이 경우 1번의 relative_product column은Null값을 갖는다. relative_product column 이 Null인지 아닌지에 따라 보통인지 곱빼기인지 상품을 구분할 수 있고, 프론트로 부터 곱빼기 여부를 받아 그 결과에 따라 해당 제품을 인식할 수 있었다.

고민 포인트

  • 연습용 DB와 실제 DB : 처음에는 클론코딩이니까 완벽한 제품 기획이 있은 후에 완벽히 입력된 DB를 가지고 API를 만들 때 사용할 수 있을 것이라 기대했다. 사실 조금만 생각해봐도 이런 (백엔드에게) 이상적인 상황이 있을 리가 없다. 이는 Agile한 마인드도 아니기도 하다. 당연히 연습용 DB를 과하지 않은 선에서 작성한 후에 실제 DB를 마지막에 입력했어야 했다. 실제로 그렇게 일이 진행 될 수 밖에 없더라.

  • 확장성에 대한 고민 : 곱빼기 옵션 때 했던 고민. 실제로 프론트와 합의한 것은 곱빼기 옵션만을 구현하기로 한 것이었지만 그 외의 김 추가 같은 다른 옵션들을 더 구현하기 위해서는 위의 셀프참조의 형태로는 힘든 것이었다. 만약 옵션을 더 추가하게 된다면 옵션 테이블이 따로 필요한 것은 뻔한 상황. 현업이나 지속적인 프로젝트를 가정했다면 당연히 옵션 테이블을 만들었어야 했었다. 아마 추후에 다시 develop하게 된다면 그 때 추가하게 되고 또 DB수정이 필요해지지 않을까?

2. API

  • 내가 맡은 부분은 회원가입과 CART 로직이었다.
  • 회원가입 로직을 구현하는 것 자체는 이미 한 번 경험했기 때문에 어렵지 않았다. 하지만 디테일하게 들어가면 고민해야 될 사항들이 있었다.

고민 포인트

  • 아이디, 비밀번호, 이메일의 형식검사(유효성검사)를 FE, BE 어디서 처리할 것인가? : 전부 BE에서 처리하면 불필요한 통신이 과하게 발생할 것이며 실시간으로 유효성 검사 요청을 보내는 건 리소스 낭비같았다. 그래서 FE 근휘님께서 랜더링으로 유효성 검사를 일차적으로 하시고 이차적으로 회원가입 요청이 들어왔을 때 백엔드에서 검사를 하는 것으로 했다. 다만 비밀번호 유효성 검사는 백엔드에서 하기로 했다. (보안상의 문제가 될 수 있기 때문)

  • 장바구니에서 FE와 통신할 때 장바구니 수량변경 또는 삭제 요청을 product_id 와 cart_id 중 어느 것을 기준으로 할 것인가? : 위의 셀프참조로 곱빼기를 정의하게 되면 곱빼기 유무에 따라 다른 product_id를 갖기 때문에 애초에 혼란을 방지하기 위해 cart_id를 기준으로 통신하기로 했다.

새로 알게 된 것들

  • get_or_create 를 사용하면 장바구니 생성을 쉽게 할 수 있다.
cart, created = Cart.objects.get_or_create(user = request.user, product_id = product.id, defaults={'quantity': 1})
            
  if not created:
    cart.quantity += 1
    cart.save()
    return JsonResponse({"message" : "UPDATED"}, status = 200)
  • annotate 를 통해 가상의 column 을 생성하고 이용할 수 있다.
from django.db.models       import Case, When

def get(self, request):
        carts = Cart.objects.filter(user = request.user).annotate(
            has_relative_product = Case(When(product__relative_product__isnull = True, then=False), default=True)
            )
  • 언더바 두 개를 이용하여 (위의 코드처럼) 참조 키를 통해 다른 column으로 접근할 수 있다.

  • Path Parameter , Query Parameter 를 사용하여 통신하게 되었다.
    RESTful하게 설계하는 것에 주의해야 한다.

  • default 값을 이용해 하나의 API로 여러 경우의 통신을 하나의 로직으로 처리할 수있다. (대표적으로 제품 리스트 필터링 로직)

반성

이번 프로젝트를 통해 반성하게 되고 보완해야 겠다는 생각을 했던 점들에 대해 이야기해보려한다.

  • trello 사용 미숙 : trello 티켓을 세세하게 정하기 어려웠다. 한 번 프로젝트를 진행해봤으니 다음 프로젝트에서는 더 세세하게 정해보도록 하자.
  • "YES, I CAN" : FE에서 요청이 들어왔을 때 나는 낙천적으로 생각하는 편이어서 대략적인 로직만 그려져도 "할 수 있다."고 말이 앞서는 편이었다. 막상 코딩을 해보면 예상치 못한 blocker들이 생기기 마련이었고 당황스러운 순간이 한둘 있었다. 기한은 여차저차 잘 맞추었지만 앞으로는 섣불리 장담하는 것을 경계해야겠다고 생각했다.
  • AGILE : agile해지는 것은 생각보다 어려웠다. 보통 내가 API작성을 마쳐도 프론트는 작업이 끝나지 않은 경우가 많았는데 이런 경우에 추후의 API를 미리 작성하거나 개인 공부, 또는 팀을 위해 기록을 한다거나 다른 기여를 했어야했다. 그러나 다른 여건이 여의치않아 내 일이 정체되어있다고 느꼈을 때 아무것도 하지 못하고 어영부영하는 나의 모습을 보았고, 이런 경우에 어떻게 해야할지에 대한 계획도 생각해보게 되었다.
  • project는 한글로 '소통'이 아닐까 싶을 정도로 첫 프로젝트 경험은 소통에서 시작해서 소통에서 끝나는 경험이었다. 옆에 있던 백엔드 창환님과 역할분담부터, 프론트와의 통신을 위한 키값을 정하는 것. 일의 순서를 상의하고 계획을 세우는 것. 정말 사소하게는 함께 점심식사를 하며 팀원들과 유대감을 형성하는 것 까지. 그래도 비교적 수월하게 소통할 수 있었던 것은 다른 팀원들의 적극적인 노력 덕분이었다.
profile
박광수입니다.

0개의 댓글