프로그래밍 공부하기

땅땅마켓 프로젝트 회고 본문

Project/Project

땅땅마켓 프로젝트 회고

ihl 2021. 4. 28. 03:00

우리동네 경매장 땅땅마켓!


땅땅마켓

우리 동네 경매장 땅땅마켓에서 여러분들의 중고 물품을 등록해 경매 주최자가 되어보세요!
등록된 물품을 입찰하고 실시간 채팅을 통해 거래할 수 있습니다.
경매를 통해 원하는 가격으로 거래하세요!

주소: https://ttangttang.shop/

깃허브: 백엔드 프론트엔드

백엔드: Node.js, socket.io, Multer, MySQL, Sequelize

프론트엔드: TypeScript, React Hooks, Redux, socket.io, Styled-Component, SCSS

배포: AWS CodeBuild, EC2(ELB), S3, CloudFront, Route53, Docker

 

기능:

  • 로그인
  • 지역기반 물품 검색
  • 실시간 입찰 및 가격 변동 업데이트
  • 경매 물건 등록
  • 나의 경매 필터링(판매 물품/입찰자 물품)
  • 채팅

[회고에 앞서]

  드디어 한 달간의 파이널 프로젝트가 끝이 났다. 프로젝트를 할 때마다 느끼는 것이지만 생각한 아이디어를 구현하기 위해 집중하는 시간은 정말 힘들면서도 즐겁다. 코딩도 재밌지만 인간은 사회적 동물이라 그런가 팀원들과 회의할 때 내가 팀원들이 생각하지 못한 부분을 알려주거나 팀원이 내가 생각하지 못한 부분을 알려줄 때 뭔가 소속감이 느껴지고 프로젝트가 다양한 관점에서 더 완벽해진다는 느낌이 들어 좋았다.

 

  사실 프로젝트 들어가기 전에는 여러 도전적인 개발 스택도 써보고, 디자인 패턴을 구현해보고 싶은 마음도 컸다. 요즘이라기엔 핫한지 꽤 된 GraphQL이나 MSA 같은 것들 말이다. 실제로 프로젝트 들어가기 전에 이 부분에 대한 공부도 했었다. 그러나 지금까지 개발하면서 느낀 점 중 하나는 개발자 외엔 서비스가 어떤 기술을 썼는지 관심이 없다는 것이다. 물론 최신 기술을 쓴다면 개발자는 뿌듯하겠지만 개발자 외에는 이 서비스가 잘 돌아가는지, 어느 정도의 기간이 걸릴지 정도만 관심 있을 것이다. 즉, 최고의 기술보다 가장 적합한 기술을 사용해야 한다. 우리의 서비스는 기획을 하고 나니 MSA를 쓰기엔 너무 단순하고, GraphQL을 쓰기엔 GraphQL을 써본 팀원이 없으며, GraphQL은 text가 아닌 file 전송 등의 처리가 조금 복잡하다고 들었기 때문에 사용하지 않게 되었다. 물론 취업 우대사항에 GraphQL이나 MSA항목이 있는 것들을 보면 아쉽지만 그보다도 개발자에겐 논리적으로 생각하는 것이 더 중요하다 생각하기 때문에 이유 없이 기술 스택을 쓰는 것보다 쓰지 않는다는 결정이 훨씬 좋다고 생각한다.

 

 

[기획]

1) 서비스 소개

땅땅마켓에서 경매하기

  땅땅마켓은 중고물품 경매사이트이다. 더 와 닿게 표현하자면 당근마켓 + 경매이다. 중고거래 시 판매자는 최대 이익을 얻고 싶지만 너무 높게 부르면 아무도 안 살 것 같다는 갈등을 하게 된다. 그래서 1234567원 같은 가짜 가격을 올려놓고 소비자로부터 가격을 선제시 받으려는 사람이 많다. 이 때는 반대로 구매자가 대체 얼마를 불러야 최저가로 살 수 있을지 고민하게 되고, 오히려 중고나라 빌런(?)과 같이 흑화 하는 경우도 있다. 즉, 중고거래에서 판매자/소비자 중 누군가는 가격 결정에 대한 스트레스를 받을 수 밖에 없는 구조이다.

 

  우리는 이를 경매를 통해 해결할 수 있다고 생각했다. 판매자는 최소 가격만 정하면 알아서 가격이 올라가고, 소비자는 너무 비싸다 싶으면 입찰하지 않으면 된다. 경매를 통해 가격 형성 과정은 실시간으로 투명하게 보이며, 판매자와 소비자 모두 심리적으로 내가 좋은 가격에 팔았다/샀다는 만족감을 얻을 수 있다. 

 

  당근마켓의 경우 생활용품위주의 직거래가 활발하게 이루어지고있다. 나름의 조사에 의하면 가격 선제시 거래가 많은 분류는 생활용품 보단 아이돌 굿즈 제품과 같이 매니아층이 있는 제품들이다. 따라서 이러한 거래를 원하는 소비자를 타겟층으로 잡아 타겟층의 차별화를 두었다.

 

 

2) 회의과정

민주적인 투표의 현장

  퍼스트 프로젝트 때 기획 과정에서 최대한 많은 것을 소통을 통해 결정해야겠다는 생각을 갖게 되었다. 지난 프로젝트 때 힘들게 구현을 해놨는데 다른 사람이 생각하는 결과물과 다른 경우가 종종 있어서 시간적으로도 낭비되고, 잘못한 사람은 아무도 없는데 서로 미안해하는 어색한 상황이 발생하기도 하였다. 그래서 이번에는 컴포넌트, 디자인 요소, 기능 로직까지 거의 모든 것을 다 같이 모여 결정했다. 회의를 매일 아침 10시, 저녁 9시에 1시간 이상씩 진행했으며 새벽 3시까지 한 날도 있었다. 남이 보면 회의가 지나치게 많고 비효율적이라고 생각할 수도 있겠지만 나는 그렇지 않았다. 소통의 부재로 인해 2번 일하는 케이스를 확실히 없앨 수 있었고, 모든 요소를 팀원들 모두가 만족하는 최고의 아이디어로 결정할 수 있었다. 또한 매일 팀원들의 업무현황을 구체적으로 파악할 수 있었으며, 개인적으로는 회의 시간까지 내가 맡은 일을 끝내야지 라는 동기부여가 되었다.

 

  회의는 주로 Miro와 Zoom을 통해 진행되었다. 우리 팀만의 특이한 점이라면 다른 팀들이 음성회의를 도입한 것과 달리 항상 화상회의로 진행했다는 점이다. 사실 회의 중에 보고 있는 것은 거의 Miro화면이라 화상회의를 할 필요가 없지 않나 생각할 수 있지만, 화상회의만의 장점이 있다. 일단 비언어적 표현이라는 것이 있지 않은가? 음성만으로는 알 수 없는 사람의 표정이나 손짓 등을 통해 팀원들이 회의에 잘 집중하고 있는지, 사실 이 의견을 싫어하고 있진 않은지 눈치(?)를 볼 수 있다. 또한 내 모습이 보여지기 때문에 음성회의보다 더 집중하고 긴장한 상태로 회의에 참가하게 된다.

 

 

[개발 로그]

즐거운 코딩^q^

  이번 프로젝트는 풀 스택으로 참가했다. 혼자 백엔드를 구성해보고 싶다는 팀원이 있어서 백엔드 중 내 업무와 관련 있는 실시간 통신 부분만 맡아 구현하게 되었다. 또한 최근 CICD에 대한 관심이 생겨 이번엔 배포도 맡게 되었다. 지난 프로젝트에서 배포 과정이 너무 어렵다 보니 배포 후에 고치고 싶은 부분이 생겨도 배포에 대한 부담으로 쉽게 고치자는 말이 나오지 않았기 때문이다. 내가 이번 프로젝트에서 한 일은 더보기를 통해 볼 수 있다.

더보기

[ BE ]

  • 서버 라우팅 설정
    • 서버 mvc 구조 세팅
  • 실시간 경매/채팅 서버 작성
    • socket.io를 이용한 실시간 이벤트 처리
    • DB 레코드 조회 및 업데이트
  • 이미지 업로드 및 정적 파일 제공
    • multer를 이용하여 클라이언트가 보내준 이미지 데이터 저장
    • 이미지 정적파일 제공
  • 에러로그 파일 기록
    • morgan, winston을 이용한 에러로그 기록

[ FE ]

  • 서치페이지
    • 데스크탑 및 모바일 반응형 UI 구현
    • 실시간 입찰 및 가격 업데이트 구현
  • 채팅페이지
    • 물품별 실시간 채팅 구현
  • 로딩 모달 구현
    • Lottie 파일 사용
  • 헤더
    • 모바일 메뉴 작성
    • 모바일 서치바 고정
  • 위치정보 수집 및 주소변환
    • KaKao 주소 변환 API 사용
  • Client 리덕스 세팅
    • ducks 패턴 구현

[ Deploy ]

  • AWS EC2, ELB를 이용한 https 서버 배포
  • AWS S3, CloudFront를 이용한 https 클라이언트 배포
  • Docker를 이용한 서버 개발/자동빌드환경 구축
  • AWS CodeBuild를 이용한 클라이언트 자동빌드/배포환경 구축

 

  이번 프로젝트를 통해 기술적으로 배운 점들에 대한 블로깅을 하려고 항목을 정리하니 주제가 10개나 나왔다. 이 항목들에 대해선 다음과 같이 링크를 남겨두고, 간단한(?) 부분들만 이곳에 적어보려 한다. (그래도 너무 기니까 더보기로 접어놓았다.)

 

1. socket.io

2. multer & static

3. Redux ducks with Typescript

4. SVG

5. Lottie

6. Responsive Web(ViewPort, MediaQuery, react-responsive)

7 ELB 에러: 배포했는데 웹소켓이 안 됨 / ELB 503 Error / ELB 502 Error

8. aws crontab 설정

9.  AWS CodeBuild

10. Docker(사용법, AutoBuild)

 

11) TypeScript도입

더보기
typescript

  이번 프로젝트는 프론트엔드에 타입 스크립트를 도입했다. 나는 C#과 같은 정적 언어에 익숙해서 처음 JS를 접할 때 정말 이상한 언어라고 생각했다. 같은 변수인데 숫자도 되고 문자열도 되고 객체도 될 수 있다고? 그렇다면 변수 x에 팀원 1은 숫자를 넣고, 팀원 2는 객체를 넣는 상황이 가능하다는 것이 아닌가? 이때 팀원 3가 들어오면 팀원 3은 얼마나 혼란스러울까?!  

  타입 스크립트로 개발을 하면서 느낀 첫 번째 장점은 JavaScript보다 코드 작성자의 의도가 더 확실히 보인다는 점이다. 함수의 파라미터가 어떤 타입인지, 없어도 되는 값인지 미리 알 수 있고, 팀원의 코드 해석에도 도움이 되었다.

 

  두 번째 장점은 빌드하기 전에 타입으로 인한 오류를 잡을 수 있다는 점이다. JavaScript는 x+y라는 코드에서 x변수에 문자열을 넣어도 빌드하기 전에는 알 수가 없지만 TypeScript는 잘못된 타입을 할당했다는 오류를 준다. 특히 VSCode에서  React 컴포넌트를 사용할 때 넘겨지지 않은 Props가 있으면 오류를 주고, 자동 완성도 지원한다.

  

 

 12) winston과 에러 로그

더보기
winston

  프로젝트를 막 시작해서 개발할 때는 에러가 발생하면 콘솔로 찍히지만 배포한 뒤에는 그렇지 않다. 따라서 로그파일을 기록하는 것은 정말 정말 중요하다. 나는 이번에도 winston 라이브러리를 이용해서 서버에 오류가 발생하면 log/날짜. error.log라는 파일로 기록하게 만들었다. 사실 우리 프로젝트는 정말 소비자들을 모으려는 서비스가 아니라 필요 없다는 생각도 들지만 서버에 로그가 없는 것은 아무리 생각해도 찝찝해서 추가했다.

 

 13) socket.io와 캐시 데이터

더보기
Cache Memory

  실시간 서비스에서 중요한 점 중 하나는 반응속도일 것이다. 실시간 경매에서 거의 동시에 두 사람이 같은 가격에 입찰 버튼을 눌렀다 생각해보자. 둘 중 한 명은 이전 가격을 보고 입찰 버튼을 누른 것과 다름이 없다. 이 현상을 막기 위해선 입찰할 때마다 현재까지의 최고가를 DB에 조회하는 수밖에 없다. 그런데 DB 조회/업데이트는 비동기라 언제 끝날 지 알 수 없고, 매번 DB를 조회하는 것도 비효율적이라는 생각이 든다. 그래서 캐시 데이터를 만들어야겠다는 생각을 갖게 되었다.

  서버에 물품 ID를 Key로 갖는 bucket이라는 객체를 만들었다. bucket은 물품의 현재까지의 마지막 가격을 갖고 있다. 즉, 입찰 요청이 오면 bucket에서 마지막 가격을 조회한 후 더 높다면 bucket의 마지막 가격 값을 경신한 후 DB 업데이트를 진행한다. 이 순간에 이전 가격을 보고 같은 가격으로 입찰 요청이 왔다면 DB 업데이트가 아직 안되었어도 bucket에 마지막 가격을 조회하고 해당 요청을 빠르게 거를 수 있는 것이다.

 

  우리 프로젝트는 실제 서비스가 아니므로 물품의 개수가 적기 때문에 객체로 캐시 데이터를 구현했지만 큰 규모라면 Redis를 이용하는 것이 좋지 않을까 생각된다. 아래 링크는 socket과 Redis를 함께 이용해야 할 때 참고할 영상이다.

www.youtube.com/watch?v=pEUwiD0kOmE

 

4) styledcomponent와 scss

더보기
styled-component

  이번에 css를 위해 scss와 styled-component를 동시에 사용했다. styled-component는 코드의 변수를 이용해서 css 값들을 쉽게 변경할 수 있지만 css가 아닌 js(tsx) 코드 파일이라 렌더링 할 때마다 해당 코드를 다시 불러오는 비효율성이 존재했다. 따라서 코드 변수에 의해 동적으로 css가 변해야 하는 부분만 styled-component로 작성하기로 했다. 

 

[후기]

1. 결과물에 대해

  결과물에 대해 만족스러운 점은 SR 때 구현해야겠다고 마음먹은 것들을 모두 구현해냈고, UI가 생각보다 예쁜 결과로 나왔다는 점이다. 이러한 UI가 나올 수 있었던 이유는 정말 모든 디자인 결정에 대해 팀원들이 같이 모여서 의견 교류와 투표를 진행했기 때문인 것 같다.

 

  아쉬운 점은 프로젝트가 팀원들의 포트폴리오로 들어갈 텐데 비회원을 위한 콘텐츠가 너무 적은 느낌이고, 프로젝트의 볼륨이 비교적 작은 점이다. 생각해보면 비회원이 할 수 있는 것은 랜딩페이지와 서치 페이지 구경뿐이다. 프로젝트의 핵심인 실시간 콘텐츠(입찰, 채팅)도 즐기지 못한다. 물건도 가격과 설명이 전부다. 입찰자가 가장 많은 경매 목록, 오늘 마감되는 경매목록 등의 콘텐츠나 물건마다 경매의 경쟁자가 현재 몇 명인지 알려주는 등의 콘텐츠가 있으면 더 흥미롭게 보이지 않을까 생각이 든다.

 

2. 코드에 대해

  코드에 대해선 아쉬움이 남는다. 처음에 팀원들과 도전적인 스택을 쓰지 않는 대신에 깔끔한 코드를 적자고 했던 것 같은데 결국 구현에 급급해서 코드 퀄리티에 많이 신경 쓰지 못했다. '응집도를 높이고 결합도를 낮추는 방향으로' 코드를 작성하려 노력했지만 적용되지 않은 부분도 존재한다. 또한 클라이언트가 불필요한 서버로의 요청을 하지 않는지, 성능 최적화할 부분이 있는지 확인해봤어야 하는데 이를 결국 하지 못했다. 게다가 배포한 후 배포 페이지를 pageSpeedInsight를 돌려보니 생각지 못한 성능개선사항들도 발견되었다. 이제 당장 취업전선에 나서야 해서 바쁘겠지만 그래도 틈틈이 할 수 있는 한 리팩터링 해봐야겠다.

 

  이번에 scss를 사용했지만 사용했다고 말하기 민망하다. scss의 강력한 기능인 내장 함수, Extend/Inheritance 등을 거의 쓰지 않았기 때문이다. 믹스 인도 미디어 쿼리를 쓸 때만 사용했다. 지금 돌아보면 scss 공부가 부족해서 어떤 때에 scss의 어떤 기능을 사용해야 할지 바로 상상이 가지 않아서 그랬던 것 같다. scss에 대한 공부가 더 필요하다.

 

3. 협업에 대해

  나는 퍼스트 프로젝트 팀 멤버 그대로 파이널 프로젝트를 진행한 케이스이다. 퍼스트 때 느꼈던 점은 팀원들이 너무 착하고 의견 존중을 잘해도 문제가 생긴다는 점이다. 다른 팀원이 한 결과물을 보고 걸리는 부분이 있으면 바로 말해야 하는데 내가 말하면 그 사람은 일을 두 번 해야 하고, 팀의 분위기를 해치는 것 같아서 말하지 못하는 것이다. 이는 결국 프로젝트 퀄리티의 저하로 이어진다. 즉, 피해를 안 주려한 행동이 결국 모두에게 피해가 간다. 그래서 이번 프로젝트를 시작하기 전에 퍼스트 때 느낀 점을 솔직하게 말하고 이번 프로젝트에서는 의견을 적극적으로 어필해달라고 요청했다. 또한 의식적으로 다른 사람들에게 다른 의견이 있는지 확인하였다. 그 결과 퍼스트보다 더 만족할만한 결과가 나왔고, 의견 교류 시 분위기도 더 좋았던 것 같다.

 

[마지막]

  앞서 말했듯이 한 달간 아이디어를 구현하기 위해 집중하는 시간이 힘들지만 너무 재미있었다. 아쉬운 점도 있지만 온전히 한 가지에 집중하여 충실한 한 달이었다. 부트캠프에 오기 전에는 굳이 부트캠프에 가는 메리트가 있을까? 혼자 공부해도 취업이 가능할 텐데라는 고민이 있었다. 하지만 프로젝트를 하면서 느낀 점은 역시 개발은 함께 하는 것이 즐겁다는 것이다. 혼자서 공부하는 것도 좋지만 다른 사람과 함께 의견을 나누며 내가 보지 못한 인사이트를 얻을 수 있고, 함께 하나의 목표를 향해 노력한다는 과정 자체가 훨씬 재미있다. 부트캠프에 오기 잘했다.

 

  한편으론 이번 프로젝트를 끝으로 부트캠프를 수료하고 취업전선에 나가야 한다는 것이 두렵다. 지원 공고에 지원하고 탈락했다는 것이 내가 잘못된 것이 아니라 회사와 나의 핏이 맞지 않았다에 가깝다는 것을 알고 있지만 그래도 앞으로 수많은 탈락과 낙심을 해야 할 것이 두렵고, 취업을 하면 적어도 2년은 다닐 텐데 한 번의 선택으로 최소 2년의 인생이 결정되는 것 같아서 긴장된다. 또한 코드 스테이츠 26기라는 공동체를 떠나는 것에 대한 아쉬움도 있다. 하지만 취업을 안 할 수는 없는 것이고 더 나은 방향으로 가려면 변화는 어쩔 수 없다고 생각한다. 물론 이 변화가 너무 커서 부담스럽지만 여하튼 그렇다. 노력은 배신하지 않는다는 말이 있지 않은가? 그간 최선을 다한 만큼 좋은 결과가 있을 것이라 믿는다. 더불어 같이 프로젝트를 진행한 팀원들도 정말 많이 노력했다는 것을 알기 때문에 lilachal팀 모두에게 좋은 결과가 있을 것이다!

'Project > Project' 카테고리의 다른 글

Song Number Book  (0) 2021.04.26
Comments