Skip to content

11.9 수 회의록

Ji Yoon Choi edited this page Nov 9, 2022 · 14 revisions

회의 내용

주제 선정 이유

  • 우리는 그나마 아는 사람들끼리 팀을 구성해서 서로의 코드 스타일이나 성향이 잘 맞는 편이라고 생각했지만, 그럼에도 불구하고 기술 스택이나 컨벤션 등을 맞춰가는 데에 꽤나 많은 시간이 소요되었다
  • 일련의 규칙 선정 시간을 겪으면서 "팀 구성 단계에서 이러한 과정을 최소화하면 좋지 않을까?" 라는 생각을 하게 되었고, 자연스레 주제를 '자신과 맞는 팀원 구하는 사이트' 로 결정하게 되었다

유저 시나리오

시나리오 1 (모집자)

Who

  • 얼리버드 최, 27세, 남성, 개발자, 진로를 정하지 못함, 아이디어 도출부터 함께할 팀원을 구하고 있음, 적극적임, 낯가림이 없음, 구체적인 프로젝트 계획이 아직 없음

What

  • 프로젝트 아이디어 도출부터 함께할 팀원을 구하고 싶음
  • 본인과 성향이 잘 맞는 사람을 구하고 싶다.

When

  • 사이드 프로젝트를 같이 진행할 팀원을 구하고 싶을 때

Where

  • 장소의 제약은 없음

Why

  • 본인이 원래 전공이 개발도 아니어서 주변에 아는 개발자도 없고, 좋은 아이디어가 떠오르지 않아서 프로젝트 시작을 못 하고 있다.

시나리오 2 (모집자)

Who

  • 농담베어 최, 25세, 여성, 개발자, 프론트엔드만 판다, 제주도에 살고 있어서 오프라인 모임이 불가능하다시피 함, 구체적인 프로젝트 계획이 짜여져 있고, 팀원도 어느정도 구성되어 있어 한 명만 더 구하면 됨

What

  • 간단한 채팅 기능과 게시판 기능, 회원가입 기능이 필요하지만, 백엔드 개발자가 없어 DB 스키마와 API 명세를 작성하지 못하는 상태임
  • 프론트엔드는 본인이 어느 정도 진행할 수 있으며, 기획자와 디자이너가 팀에 이미 참여하고 있기 때문에 백엔드 개발자를 구인중임

When

  • 기획과 디자인이 이미 나와있기 때문에 최대한 빨리 마지막 백엔드 팀원을 구하고 싶음
  • 마지막 팀원이 합류하는 대로 바로 프로젝트를 시작할 예정

Where

  • 에브리타임 앱 처럼 집에서 다리 쭉 뻗고 편하게 팀원을 구할 수 있으면 좋겠다

Why

  • 프론트엔드 독학은 했지만 팀 프로젝트 경험이 부족하여 이번 기회에 자신과 맞는 팀원과 함께 과제를 진행해 보고 싶음
  • 팀원 전체가 Typescript 를 사용하기로 합의가 되어있는 상태라, Java/Spring이나 Django를 사용하는 백엔드 개발자보다는 Node.js 관련 지식을 가지고 있는 개발자를 원하는 상황

시나리오 3 (등록자)

Who

  • 리미티드 한, 25세, 남성, 개발자, 백엔드에 관심이 많음, 프로젝트를 하고 싶지만 총대를 매고 팀원을 모집하기에는 낯을 조금 가림, 아직 아이디어가 없음

What

  • 여러 사람과 함께 프로젝트에 참여하기
  • 프로젝트의 백엔드를 담당하길 원함

When

  • null null

Where

  • 언제든 사용할수 있음

Why

  • 직접 팀원을 모집하기에는 부담스럽고 아직 구체적인 아이디어는 없지만 자신의 기술 스택에 맞는 프로젝트에 참여하기 위해서

시나리오 4 (등록자)

Who

  • 솔드아웃 서, 32세, 여성, 개발자 겸 기획자, 프론트엔드에 관심이 많으며, 원래는 기획자로 활동하였기 때문에 개발자 지인을 사귀고 싶음, 본인과 관심 분야가 겹치는 사람들과 소통을 하고 싶어함

What

  • 나와 관심분야가 같고 코드 스타일이 비슷한 사람을 찾아서 소통하고 싶음

When

  • 시간 제약 없이 언제든지 하고 싶을 때 하길 원함

Where

  • 좀 더 다양한 사람들과 소통할 수 있도록 공간제약이 없는 온라인 공간이 좋음

Why

  • 공통관심사가 있어서, 활발하게 소통하고 함께 배워나갈 수 있는 개발자 지인을 원함

API 명세

API 주소 API 유형 기능 그룹 비고
/auth/login/ POST 로그인 회원관리 (auth) 응답코드에 따라 메인 페이지 또는 회원가입 페이지로 이동 (프론트엔드에서 작업)
/auth/logout POST 로그아웃 회원관리 (auth)  
/auth/check GET 로그인 여부 확인 회원관리 (auth) 현재 로그인이 되어 있는지 여부를 쿠키를 통해 확인
/auth/validate?id=ABC GET 아이디 중복 및 유효성 확인 회원관리 (auth) 아이디는 쿼리스트링으로 전송, 아이디 유효성 및 중복 체크
/auth/register POST 회원가입 회원관리 (auth)  
/auth/withdraw DELETE 회원 탈퇴 회원관리 (auth) DB에서도 데이터 아예 삭제
/detail/edit PUT 상세프로필 수정 프로필  
/detail?id=ABC GET 상세프로필 열람 프로필 아이디나 고유값은 쿼리스트링으로 전송
/profile?stack=frontend&filter1=A&filter2=B&filter3=C&liked=true GET 간략한 프로필 리스트 열람 프로필 리스트 쿼리가 있으면 쿼리 내용에 맞춰 필터링, 쿼리가 없을 경우 전체 리스트 가져오기
/like POST 좋아요 추가 좋아요 새로운 좋아요 정보가 DB에 저장되므로, POST
/like DELETE 좋아요 삭제 좋아요 기존의 좋아요 정보가 DB에서 삭제되므로 DELETE
/like?id=ABC GET 좋아요 리스트 조회 좋아요 아이디나 고유값은 쿼리스트링으로 전송
  • 기술 스택 리스트: 프론트엔드 - 백엔드 간 공용 상수로 분리 (예시: Javascript: 1, Typescript: 2)

페이지 라우팅

페이지 주소 기능 비고
/ 메인 페이지 /main 으로 리디렉션
/?stack=frontend&filter1=A&filter2=B&filter3=C&liked=true 메인 페이지 (필터와 함께) 쿼리가 있으면 쿼리 내용에 맞춰 필터링, 쿼리가 없을 경우 전체 리스트 렌더링
/login 로그인 페이지  
/detail/ABC 유저의 상세페이지 열람 id는 주소에 붙이기
/mypage 유저 자신의 페이지 열람  

ERD, 자료 구조

관계형 DB - MySQL 사용

마스터클래스 준비

멘토링 준비

멘토링

회원가입을 따로 구현할 것인지?

  • 회원가입이라기보단 깃허브 / 구글 로그인을 받고, OAuth 인증 절차를 거친 후 추가적으로 필요한 정보만 받아올 예정

타겟이 PC 위주인지?

  • 현재는 PC 위주로만 생각하는 중 => 시간상 PC / 모바일 둘 중 하나만 고르는 것이 좋겠다

JWT 관련 질문 => 우리만의 토큰을 발급할 것 같다

  • 액세스 토큰의 해킹 위험성을 줄이기 위해 리프레쉬 토큰을 같이 사용하는데, 서버와 클라이언트가 주고받는 절차를 어떤 식으로 구성해야 보안상 / 리소스적 이점이 있을지

    • 리프레쉬 토큰이 탈취되면 서버에서 삭제 시도 등으로 보안을 막을 것
    • 이 방식이 좀 낯설다 => 토큰을 하나만 사용하는 회사도 있음
    • 토큰 하나만 사용하는 방법: 액세스 토큰의 만료 기간이 길고 (1~2주 정도), 매번 사용할 때마다 새로 발급을 해 준다
    • 리프레쉬 토큰을 사용함으로써 얻는 보안적인 이점은 조금 애매하다
    • 리프레쉬 토큰은 서버에만 저장하고, 액세스 토큰은 서버와 클라이언트에 동시 저장, Valid 여부 뿐만 아니라 DB 에 저장된 액세스 토큰 값과 똑같은지 체크한다
    • 탈취되었을 때 방어가 전혀 안된다... Valid 체크를 추가로 진행해야 함 => 서버에서 추가적인 절차를 진행해야 한다
  • 로그인을 2주동안 잡는 경우도 있고 어렵긴 하다

OAuth

  • 로그인 처리에 대한 부분을 사람마다 다르게 구현하더라... 방식을 하나로 통일하는 것이 시간이 걸릴 것

  • 구글 / 깃허브 토큰값은 유지 시간이 매우 짧다

    • 계속 Refresh를 하거나
    • 구글 / 깃허브 토큰을 이용하여 데이터만 받아오고, 우리가 자체적으로 토큰을 만들어서 지속시간을 조금 더 길게 잡거나

NOT NULL vs NULL

  • NULL 보다 NOT NULLNULL 체크를 할 필요가 없어 성능이 좋다?? NULL로 저장하기 vs '' (빈 문자열) 로 저장하기
    • 성능은 DB마다 차이가 있다
    • 성능 관점으로 보기보단, NULL 이 담고 있는 의미에 대해서 생각해보는 것이 좋을 것 같다
    • NULL은 값이 없음을 나타내는데, '' (빈 문자열) 은 '값이 없다' 라는 의미가 퇴색되는 감이 있다
    • 실질적으로 필요한 것만 NOT NULL로 두고, NULL도 적절히 사용하는 것이 좋다

검색 바 API 호출 위치

  • 필터링 옵션이 체크될 때마다 API 호출을 시킨다 vs '선택 완료' 등의 버튼을 클릭할 때만 한번에 API 호출을 시킨다
    • 전자: 사용자에게 조금 더 좋은 UX 경험을 줄 것 같다
    • 후자: 서버에 부담이 적다
    • 멘토님: UX 경험을 우선시해야 한다고 생각함, DB 때문이라기에는 이것을 해결할 방안이 프론트엔드 시점으로도 꽤 있다
    • 대표적인 것이 Throttle 기술: 체크박스를 1초에 10번 눌렀다고 10번 요청이 가지 않도록, 특정 기간동안 한 번의 이벤트만 발생할 수 있게 막아주기
    • 백엔드에서도 부하를 줄일 수 있는 방법이 많다 => Redis 와 같은 캐시를 붙이거나, 검색과 같은 경우엔 검색에 최적화된 기술들을 붙여 사용함
    • Elastic Search: 특정 체크박스를 선택했을 때 어떤 데이터가 나오는지 미리 인덱싱을 해두고, 부하가 많이 오더라도 인덱싱한 결과값에서 빠르게 데이터를 가져올 수 있다
    • 데이터가 많을 경우 DB에 부하가 생기기 마련임, JOIN QUERY 같은 걸 이용하기보단 (검색에 한해서) Elastic Search 를 붙여 별도의 인덱싱 과정을 덧붙이는 일이 많다
    • 프론트엔드 - 백엔드 둘다 고려해봄직한 사항인 것 같아요
    • 다만 저런 체크박스 형태의 검색창은 캐시 히트율 (Cache Hit Rate) 가 비교적 낮아보인다 (다른 사람들과 키가 겹칠 일이 드물어보임) => redis cache 의 활용이 그렇게 유의미할 것 같진 않다

기획서와 ERD 관련, 조금 더 덧붙이거나 고려해봄직한 요소가 있을지?

  • 이 프로젝트와 비슷한 프로젝트를 멘토링해 본 경험이 있다

  • 우선순위 Stacks => 여러 스택이 쌓일 텐데 어떻게 이용할 것인지?

    • 구분자를 이용해서 데이터를 연속해서 저장하고, 클라이언트 측에서 split 을 하려고 했다
    • 클라이언트 쪽에서 스택 종류를 따로 가지고 있어야 할 듯하다
    • 멘토님: 프로필을 생성할 때, Stacks에 이미 값을 넣었다는 사실에 관한 validation이 필요할 듯한데
    • 프론트엔드의 정보는 신뢰할 수 없다는 것 (해커가 보냈는지, 우리가 보냈는지) 을 염두에 두어야 한다
    • => 우리가 정해놓은 스택에서만 고를 수 있도록 설정하려 했다 (백엔드에서도 같이 사용하는 공용 상수를 가지고 검증 절차를 거칠 예정)
    • 백엔드에서 Validation 관련해서 고민할 거리가 굉장히 많을 것 같다
  • ERD 상에서 말씀드릴 만한 부분은 많지 않을 듯싶어요

env 파일은 어떻게 관리하는 것이 좋을까

  • cross-env

    • 환경을 여러 개 구성을 해놓는다 (로컬용 - local, 개발용 - dev, 배포 직전 작동 체크용 - stg, 배포용 - real 등)
    • local, dev와 stg, real은 아예 별개의 DB를 바라봐야 한다
    • 또한 환경별로 서로 다른 env 를 주입하여 사용해야 한다
      • 보통 Host 주소와 같은 값이 들어갈 듯 싶다
    • 여러 환경변수를 코드 내에서 조건문으로 분기하여 가져와 사용할 수 있다
  • env 파일은 .gitignore 을 이용하여 깃허브상에 올리지 않는데,

    • 올리긴 합니다
    • 시크릿 키들은 어떻게 하는지? => env 에 넣지 않는다
    • 다른 방법으로 injection을 고려한다
    • 보통 서버를 배포하는 스크립트에서, 별개의 파일에 들어있는 환경변수들 (또는 Github-secret 과 같은 변수) 을 가져와서 배포 과정에서 따로 주입한다
  • 시크릿 키를 실수로 push를 하는 순간 이 키는 무조건 공개되었다고 생각하면 된다 (커밋을 제거하더라도 git으로 복구할 수 있다)

    • 만약 실수로 Push하면, 그 키는 아예 삭제하고 새로운 키를 발급받아야만 한다

배포 방식

  • Github Actions
    • workflow 안에서 Github Secrets 안에 들은 변수들을 주입시켜줄 수 있으므로, 비밀 키들은 이렇게 관리하자

고려할만한 기술 스택

  • 어느 정도의 동시 접속자 수까지 대응할 것인지? 가 조금 중요
    • 동시 접속자 수에 따른 기술 스택이 전부 다르다
    • 사실 지금은 대규모 접속이 예상되지 않기 때문에, 지금만으로도 충분할 것 같다
    • 오히려 대규모 접속을 고려한 기술을 사용하게 되면, 공부할 내용이 너무 많아지며 리스크가 커질 수 있다 (기술 부채)
  • 기술 스택이 옛날 것 / 너무 과한 기술 스택 => 기술 부채로 이어짐
    • 더 많은 스택을 고려해보는 것도 좋겠지만, 한정된 시간에 빠르게 완성도 높은 프로젝트를 구현하는 것이 더 좋아 보인다

채팅 기능을 추가한다면 DB에 저장을 어떻게 할까요?

  • 채팅 데이터는 NoSQL에 저장하는 것이 효율적이다?
    • 정답이 없는 문제긴 하다
    • RDBMS - NoSQL 차이: 정합성이 중요한가? 약간 뒤틀려도 상관없나?
    • 채팅은 정합성이 중요한 것은 아니다 (회원, 좋아요 등은 정합성이 중요함)
    • 유저 DB도 NoSQL을 사용하는 것이 성능은 훨씬 좋다
  • 관계형 DB의 이점: 관계형 DB를 JOIN해서 API로 한번에 데이터를 내려줄 때 이점을 가짐
    • 요즘은 각각의 데이터가 별개의 API를 따르기 때문에, 사실상 관계성이 그렇게 중요하지 않아 보임
    • NoSQL DB는 비정규화된 데이터 => 채팅 한줄 한줄을 별개의 키로 잡아 각각의 Document로 받아오는 것은 부담이 될 수 있다
      • NoSQL은 하나의 도큐먼트로 구성이 된다 => 얼마나 잘 비정규화했는지가 NoSQL의 핵심
      • 20개씩 잘라서 하나의 도큐먼트에 담고 페이징하는 등의 방법
      • 카카오톡도 스크롤해서 위로 올릴 때 여러 개의 대화 내역이 불러와진다 => 페이지네이션 되어 있다는 증거
  • 이 프로젝트에서는 NoSQL이 조금 더 적합해보이긴 한다
    • 지금 바로 NoSQL을 도입해도 상관없어 보임
    • 유저 데이터를 비정규화된 하나의 테이블로 잡는 것이 적절하지 않을까?
  • 관계형 DB는 컬럼이 너무 많아도 좋지 않다 => NoSQL은 상관없는지?
    • NoSQL은 관계형 DB에 비해 엄~~~청나게 빠르다 (bson => binary json 으로 저장되므로 도큐먼트 하나의 크기가 매우 작다)
  • NoSQL 도입 시
    • 좋아요 데이터만 별도의 테이블로 나누고 (무한히 커질 가능성이 있음), 나머지는 무한히 증식할 만한 필드가 없어보여 하나의 테이블로 뭉쳐도 상관없어 보인다

Github Action으로 물리서버에 자동배포하기

멘토님 블로그

얼리버드

프로젝트

개발일지

스프린트 계획

멘토링

데일리 스크럼

데일리 개인 회고

위클리 그룹 회고

스터디

Clone this wiki locally