e-커머스 클론 프로젝트를 회고하며

solee·2022년 3월 13일
0

TIL

목록 보기
7/20

✅ 프로젝트 및 사용된 기술 소개

클론 프로젝트가 있었다. 프론트단 3명과 백단 3명이 한 팀이 되어 한 사이트를 타깃삼아 똑같이, 혹은 비슷하게 구현해보는 것이다. 기간은 2주였고 타깃 사이트는 e-커머스 사이트다.

-완성본-

과일을 판매하는 사이트로 결정되었다.


Python을 기반으로 Django web fremework, Bcrypt 등이 사용되었고 DB는 MySQL을 사용하였다. 나는 Oracle을 사용해 본 적이 있어서 MySQL이 많이 다를지, 다르다면 얼마나 다를지 걱정했는데, django ORM을 사용하게 되어 오히려 완전히 다른 방식을 사용하게 된 것이 꽤 신선했다.

또 ORM을 처음 사용했을 때에는 그냥 SQL 쿼리를 작성하는 게 더 좋다고 생각했는데, 막상 여러 방법으로 사용해 보니 방법도 다양하고 좋았다. 다만 SQL문을 작성할 줄 아는 것과 모르는 것의 기본 개념 이해 자체가 다르지 싶어서 조금 아쉬운 부분은 있었다. 또 모델링이 많이 복잡할 경우에는 오히려 ORM이 사용하기 더 까다롭기도 했다.

다시 만져 보고 느낀 것인데, 완전히 언어 같은(프로그래밍 언어 말고 진짜 언어!) SQL 쿼리문을 내가 제법 좋아한 모양이다. 이쪽으로 조금 더 깊게 공부해서 SQL을 다루고 싶기도 하다.



✅ 역할

나는 얼렁뚱땅 PM 비슷한 것을 맡아 진행하게 되었는데, 거창한 일을 한 건 아니고 대략적인 일정 관리나 회의 진행 정도를 맡았다. 얼렁뚱땅 맡았다는 것은 어쩌다가 그렇게 됐다는 것으로, 팀에서 누군가를 지정하고 그에 대한 책임을 느껴서 그랬다기보다는 성격상 조용한 것보다 이렇게 해 볼까요? 하고 말을 먼저 꺼내다 보니 그렇게 된 것이다. 프론트쪽에서도 좀 더 주도적으로 진행하는 사람이 있었고 백에서는 그게 내가 되었다.
회고 미팅을 진행하며 이야기가 나왔는데 정하지 않고 진행한 것이 더 도움이 된 것 같다고 해서 마음을 놓기도 했다.

다양한 기능을 개발하는 게 생각보다 재미있기도 했다. 얼핏 생각하기에 이렇게 하면 되겠구나 견적이 뽑히는 경우도 있었고 아닌 경우도 있었지만, 생각보다 코드를 효율적으로 짜는 게 어려웠다. 대신 그만큼 코드를 살펴보다가 쓸모없는 변수, 분기를 쳐내거나 새로운 방법을 구현해 기능이 잘 작동될 때의 즐거움이 크기도 했던 것 같다.



✅ 내가 구현한 기능

Agile하게 구현하자!

agile이라는 표현은 많이 들어보았다. 정보처리기사를 공부할 때에도 들었고, 개발자 커뮤니티에도 자주 나오던 표현이기도 하기 때문이다. 또 프로젝트를 시작하기 전에도 agile과 scrum에 대해,그리고 1,2차 sprint와 daily meeting에 대해 이야기를 듣고 시작했기 때문에 더 신경쓴 것 같다. 2주짜리 짧은 프로젝트였기 때문에 스크럼의 주기를 잡을 수는 없었고, 한 기능을 구현할 때마다 사용 가능한 기능인지 확인하고 싶었다.

MVP에 대해 고민했었는데, 이 이미지를 보고 속이 시원해졌다!
이걸 기반으로 설명해보자면 아래와 같다.

나는 이 프로젝트에서 상품 리스트에 관련된 api를 구현했다. 리스트에 관련된 여러 api가 있는 것은 아니고, view 하나와 def 하나만 있었다. GET Method를 사용하였는데, 여기서 agile하게 구현하는게 어떤 것일지, 아무래도 해 본 적이 없다보니 조금 고민이 있었다. 또 리스트를 리턴한다는 목표에는 카테고리별로 값을 리턴하고, 필터별로 값을 리턴하고, 페이지별로 값을 리턴한다는 작은 과제들이 있었다. 당연히 이것들을 한번에 구현하는 것은 쉽지 않았다.


- 제일 기본적인 기능 구현

그래서 일단 아주 기초적인 기능만 구현했다. 다른거 다 제치고 상품 전체의 리스트를 리턴하게 하는 것이었다. 리스트 자체를 작성하는 것은 어렵지 않았다. csv로 DB에 데이터를 삽입한 후에 전체 목록을 전부 리턴하도록 한 후 프론트와 붙여 보았다. 위의 이미지로 따지면 맨 마지막의 1번이 되겠다.


- 카테고리 필터 기능 구현

작은 시행착오들을 겪은 후에 통신이 완료된 후로는 조금 더 수월했다.
원래부터 타깃 사이트의 카테고리가 적기도 했고, 나는 조금 더 쉽게 하기 위해 카테고리의 PK를 프론트로부터 전달받을 수 있도록 했는데, 타깃 사이트에서도 cate_no=1 라는 쿼리 파라미터를 사용하고 있었다. 이것을 따라 프론트로 넘어가는 데이터의 키 값을 상의해 정한 후에, GET Method의 쿼리 스트링으로 넘어오는 카테고리를 받아 filter에 사용하도록 했다. 주소에는 category=1 같은 식으로 데이터가 넘어왔고 해당 데이터를 category_id라는 변수에 저장해 사용했다.

이렇게 하니 전체 상품에 대한 데이터가 따로 필요했는데, 어차피 전해져 오는 category_id를 "all"이라는 string으로 전달받은 후 이것을 사용해 분기를 나눴다. 처음에는 Q객체에 대해 몰라 if문으로 filter() 인지 all()인지 구분해 리턴했다.

또 상품 리스트를 리턴할 때에는 특별한 필터 요소가 필요 없다고 생각해서 category라는 키가 전달되지 않을 경우 자동으로 전체 상품을 리턴하도록 .get()을 통해 default값을 "all"로 설정해 주었다.

이후에 Q객체에 대해 알게 되었다. 그래서 if문으로 Q객체에 값을 넣는 것까지 끝낸 후에는 그냥 filter()에 q객체를 전달하는 것으로 마무리가 됐다.
또 category_id가 한번씩 null이나 다른 값이 오기도 해서 이 경우에 에러를 해결할 수 있도록 리스트에 정해진 값을 담아 validator로 사용했는데, 이 부분만 따로 빼서 함수로 만들어 ValueError를 raise하도록 수정했다.



- 정렬 기능 구현

기대했던 정렬 기능은 생각보다 간단했다. ORM 덕에 쿼리셋에 .order_by를 붙여 어떻게 정렬할지 기준만 전달하면 되었던 것이다. 그래서 if문으로 분기를 나눠 출력한 쿼리셋을 먼저 구한 후 해당 쿼리셋에 .order_by()를 더해 리턴했다. 그리고 중요한 order_by의 인자는 처음부터 프론트에 오름차순 내림차순, 테이블과 동일한 값을 가진 키값을 전달하도록 했다. 해당 값을 받아 마지막에 정렬하도록 수정했는데, 이 정렬은 기본값을 가격 오름차순으로 설정하기로 했으므로 분기가 따로 필요없이 마찬가지로 .get()을 사용해 default값을 "price"로 정했다.



- 페이징 기능 구현

페이징 같은 경우는 이전에도 django paginator를 사용하기 위해 이리저리 애쓰면서 포스팅을 한 적이 있다. 처음에는 django paginator를 사용했는데, 그냥 리턴하려니 리스트 형태가 아니라 불가능했다. 검색도 열심히 해 봤지만(5시간 정도..) 결국 포기하고 일반적인 방법으로 직접 페이징을 계산했다.
이미 쿼리스트링이 꽤 길게 이어지기도 해서 페이징은 내가 직접 구현해보자 하는 마음이 들기도 했다.

요청은 몇 페이지를 원하는지에 대한, page값만 받았다. page 크기는 정해져 있었고, 이 값으로 offset과 limit를 계산했다. 그리고 총 페이지 수와 함께 정렬까지 마친 쿼리셋에 [offset:limit]로 슬라이싱해 리턴했다.





✅ KPT 회고

이번 프로젝트에 대해 KPT 회고 방식으로 되돌아보고 싶다. 이래저래 아쉬운 점도 많았지만 즐겁기도 했다. 회고를 통해 다음 프로젝트에는 더 조심하고 더 잘 하고 싶다.


Keep

  • 좋았던 점이라면 일단 프로젝트가 꽤 agile하게 진행되었다는 점이다. 각 기능을 구현할 때마다 각 기능과 페이지의 담당자가 통신해 가면서 진행했고, 그 덕에 작업 속도가 충분히 나와 목표한 것들을 상당히 달성할 수 있었다. 서로 협조적으로 요청하고 질문해가며 진행한 덕에 더욱 즐겁게 프로젝트를 해나갈 수 있기도 했다.

  • 개인적으로는 코드가 제법 마음에 들게 짜졌다는 것이다. 한번씩 막히는 부분이 있어도 노려보면서 이리저리 생각해 보니 어떻게 하면 더 예뻐지겠다, 더 깔끔해지겠다는 것이 보였다. 계속해서 공부하고 수양하면서 어떤 방식이 도움이 될지, 더 효율적일지를 꾸준히 생각해야겠다고 다짐했다.


Problem

  • 백엔드와 프론트엔드가 붙여 보는 것은 잘 진행되었는데, 아쉬운 점이 없을 수는 없다. 예를 들어 백엔드에서는 어떤 에러가 있으면 이렇게 리턴해야겠다고 결정했는데, 막상 그 내용에 대해 프론트가 알 수 없어서 헷갈려하는 일이 꽤 잦았다. 이런 내용을 뒤늦게 노션에 정리해서 안내했는데 그 전에 미리 기능별로 안내했으면 좋았을 것이다.

  • 또 페이지 단위로 생각하지 말라는 조언이 있었는데, 당시에는 그게 어떤 건지 모르겠어서 어려웠지만 어느정도 마무리되고 보니 알 것 같았다. 트렐로 티켓 자체를 페이지가 아니라 기능별로 작성했더라면 훨씬 쉬웠을 것이다.
    이에 대한 연장선이기도 한데, 트렐로며 타깃 사이트며 노션이며 다양한 페이지에 계속해서 접속해야 했는데, 이런 것들을 모아서 관리하는 페이지가 있었으면 훨씬 수월했을 것 같다는 아쉬움이 있었다. 한번씩 다른 팀원에게 이러이러한 내용 어디에 있었죠? 하고 서로 질문하는 일이 있어서 아쉬웠다.

  • 프론트와 백의 소통도 중요하지만, 백엔드끼리의 소통도 못지않게 중요한데 아쉬운 부분이 있었다. 결정할 때에 꼭 짧게라도 회의를 진행해 의견을 찬찬히 수렴하고 결정하는 과정이 필요했는데, 성격이 급해 놓칠 때가 왕왕 있었다. 짧은 프로젝트니만큼 이런 결정 하나하나가 크게 다가오기도 했고 아쉬운 손실로 남기도 했다. 또 스트레스 상황에 말실수를 하기도 했는데, 언제든 발언할 때에는 상대방의 상황과 기분을 생각하고 이해하는 일이 더욱 중요하다고 느꼈다.

Try

  • problem에서 어느 정도 해결책을 같이 생각했는데, 다른 팀의 프로젝트와 진행 방식을 보며 알게 되고 느낀 방법들을 다음 프로젝트에는 꼭 진행해 보고 싶다. 예를 들어 DB에 들어있는 데이터와 그 흐름에 대해 단순히 모델링으로만 설명하는 것이 아니라 예시나 스크린샷을 통해 정확히 안내했다면 헷갈리는 부분이 훨씬 적었을 것이다.
    또 프론트에서 어떤 용어를 사용하는지, 백에서는 어떤 용어를 사용하는지 미팅이나 대화 도중에 모르는 부분이 있다면 따로 트렐로나 노션 등에 적어 서로 설명하면서 양측이 이해하는 데에 도움을 줄 수 있는 방식을 사용하고 싶다.

  • problem에서는 코드의 효율에 대해 이야기했는데, 조금 더 효율적으로 고민하는 것부터 시도하고 싶다. 효율적으로 고민한 결과라면 효율적인 방식으로 검색도 하고 서로 리뷰도 하고 참고도 할 수 있을 것이다.




마치며

이렇게 빠르게 2주가 지나갔다는게 믿기지 않는다. 아닌게 아니라, 사흘 정도 지난 것 같은 기분이다. 그만큼 충만하고 코딩으로 꽉 찬 시간을 보낸 것 같다. 이번 프로젝트에서 있었던 좋은 점, 아쉬운 점들을 가지고 다음 프로젝트와 그 다음 프로젝트, 그리고 앞으로 개발할 모든 시간에 긍정적으로 적용해 더 나은 사람과 더 나은 개발자가 되고 싶다.


profile
DA DA DA

0개의 댓글