데모 간략하게 볼 수 있을까요???
프로젝트 하면서 기술적으로 어려웠던 부분이 있었나요??
rest api 방식과 graphql 방식을 사용해보시면서 어떤 차이점을 느끼셨나요?
테스팅을 위해 jest, cypress를 사용하셨다고 했는데 슬라이드에서는 설명이 없어서요. 혹시 테스트 관련해서 추가 설명 해주실 수 있나요?
채팅이 추가되는 mutation을 드라이버가 출발지까지 오는 페이지 또는 목적지까지 가는 페이지에서 구독을 하도록하여 채팅이 추가될 때마다 구독자에게 추가된 데이터를 받을 수 있게되어 구현할 수 있었습니다.
## 예상질문
- 실시간 기능들에 대한 테스팅은 어떻게 진행했는지?
- 실시간 테스팅은 진행하지 못함. 테스팅은 필수기능 구현사항이 끝나고 시간이 남는다면 도전해볼만한 과제로 정했고
- 남은 시간을 고려해서 계획을 세울때 서버쪽 핵심 API, 로그인 회원가입 E2E 테스트를 정도를 작업범위로 잡는것이 좋다고 판단함
- Redux에는 어떤 상태를 넣고 관리했는지??
- => 필요한 정보를 매번 서버에게 요청하는 것이 비효율적이라고 생각해서 자주 사용되는 정보는 Redux에 넣어서 관리 및 사용
- 사용자에 대한 정보
- 아이디 -> 요청을 할 때 어떤 사용자가 했는지 알기 위해서.
- 위치 (드라이버) ->
- 오더에 대한 정보
- 현재 사용자가 진행중인 오더 -> 채팅, mutation, sub, 등에서 오더의 아이디가 필요한 경우가 많음
- 오더가 진행 중이라면 오더의 상태(callOrderStatus)
- 출발지 도착지 -> 드라이버와의 거리를 계산하기 위해 사용
- 매칭된 드라이버와 드라이버의 차 정보
- 개발하면서 겪었던 어려운 점?
- graphQL을 사용할 때 Schema Definition Languages에 대한 type을 모두 지정해줘야 되는 부분이 어려웠다 -> GraphQL codegenerator인 codegen을 이용하여 SDL만 작성하고 실행하면 알아서 타입을 파싱한 후 타입스크립트 파일을 반환하도록하여 해결했습니다.
- GraphQL을 사용하면서 인증처리 문제 -> 하나의 endpoint에서 모든 요청을 처리하는 GraphQL에서 특정 query나 mutation에 인증처리를 하는 부분이 어려웠습니다. 저희가 생각한 방법은 인증이 필요없는 로그인, 회원가입은 REST API로 나머지 인증이 필요한 요청은 GraphQL로 해결하자! 라고 생각하여 해결을 했습니다. 하지만 저희가 이 방법을 구현하면서 로그인, 회원가입 두 가지를 해결하기 위해 복잡한 redux-saga를 써야할까? 라는 생각이 들었고, 추후 리팩토링 과정에서 Apollo Schema Directives라는 스펙을 알게되어 해당 기술을 사용하여 모든 요청을 GraphQL에서 처리하면서 특정 query나 mutation에 인증처리를 할 수 있었습니다.
- Google API 어느것을 무엇을 위해 사용했는지?
- Google Place -> 위치를 검색할 때 자동완성 기능을 넣기 위해서 사용
- Google GeoCoding ->
- Google Direction -> 출발지와 목적지를 선택 후 이동경로를 찾고 표시하기 위해 사용
- cypress, jest 를 선정한 이유가 있었는지 ?
- jest: api 통합 테스트를 하며 사용했는데, 일단 쉬운 문법으로 코드를 테스트할 수 있어서 좋았고 `apollo-server-testing`모듈과 함께 통합 테스트를 진행하며 api가 잘 동작하는지 확인하기 좋은 것 같아 사용함
- cypress
- 사실 초반에 프론트엔드 테스트를 위해 jest나 storybook을 사용하자는 의견이 나왔는데 구글 맵같은 외부 라이브러리를 사용하고 실시간 socket통신이 많은 우리 프로젝트의 특성상 jest를 잘 사용하기는 어려울 것 같다는 이야기가 나옴
- 프론트엔드에서 유닛 테스트를 진행하기에도 구조가 쉬운 유틸 함수가 많아 이게 의미가 있는 테스트일까? 란 의문을 가졌음
- 그래서 아에 FE와 BE를 한번에 시나리오 동작테스트를 하기 위해 E2E 테스트 프레임워크인 cypress를 사용하기러 함 (몇 주 전에 열린 fe conf에서 tdd관련 세션을 시청했는데 cypress는 한번 사용해보면 좋다는 의견을 들어서 참고)
- NCP에 배포할 환경 구성을 어떻게 했는지?
- nginx로 리액트 빌드 파일 띄우고 api서버로 연결해 주는 프록시 서버로 사용(외부 포트와 내부 포트를 다르게 설계)
- db는 ncp에서 제공하는 mongodb server 사용
- GraphQL과 REST API를 사용해봤을 때 서로의 차이점
- REST에서는 여러 Resource에 접근하고자 할 때 여러 번의 요청이 필요하지만, GraphQL에서는 한번의 요청에서 여러 Resource에 접근할 수 있습니다. (하나의 endpoint)
- REST에서 각 요청은 해당 엔드포인트에 정의된 핸들링 함수를 호출하여 작업을 처리하지만, GraphQL에서는 요청 받은 각 필드에 대한 resolver를 호출하여 작업을 처리합니다.
- 정확히 원하는 데이터만을 받을 수 있음 (over-fetching, under-fetching 해결).
- 요청 응답 구조가 정해져있는 REST API 와 다르게 내가 원하는데로 응답의 구조를 바꿀수 있어서 편했다.
- REST API를 사용하면 비동기적으로 상태를 관리해야 하는 경우가 종종 있는데 GraphQL의 경우 apollo-client가 해당 부분을 대체해 줘서 편했다.
- 아폴로 클라이언트 캐싱전략? 또는 이번 프로젝트를 진행하면서 아폴로 캐시를 사용했는지?
- 처음에는 캐시 정책으로 cache-first 사용하여 캐시에 데이터가 있다면 캐시데이터를 사용하고 그렇지 않다면 서버에 요청을 해 데이터를 가져오도록 하고 있었음. 하지만 이렇게 사용했을 경우 드라이버와 사용자간의 채팅 시 사용자가 채팅을 보내면 사용자의 캐시 데이터를 업데이트 되지만 드라이버의 캐시데이터는 업데이트 되지 않아 캐시 정책을 network-only로 바꿨음. 캐시로 인해서 업데이트된 데이터를 불러올 때 업데이튼 된 정보가 들어오지 않아서 캐시 정책을 변경.
- 리덕스 장단점 << 실무에서는 불필요한 렌더링으로 인해 잘 사용하고 있지 않음
- flux패턴으로 정해진 구조에 따라 구현하기 쉽다고 생각
- 다양한 미들웨어를 활용할 수 있음 /ex redux saga 등
- 불필요한 렌더링으로 프로젝트가 커질수록 퍼포먼스가 좋지는 않음
- 라이브러리 다른 대안 생각
- MobX: 정해진 구조가 없어서 초기에 구조를 잡는게 어려울 것 같다고 판단함, MobX에 대한 구조를 회의하고 적용할 시간에 다른 라이브러리를 쓰는게 더 좋을 것 같음 (데드라인이 있는 과제였기 때문에)
- Apollo Client 자체 상태 관리: 2-3주라는 단 기간에 아폴로의 로컬 캐시 관리를 이해하기 힘들다고 판단함
- Context API + React Hooks: 프로젝트에서 전역 상태관리를 크게 사용하지 않았기 때문에 context api도 좋을 것 같음
- recoil: 기존의 react hooks와 굉장히 닮아있는 문법을 가지고 있어 쉽게 배울 수 있다고 생각, 이번 프로젝트에 적용해도 좋을 것 같음
- express를 왜 사용했는지?
- apollo server express를 사용한 이유?
- apollo server에서도 적용할 Nodejs 미들웨어를 사용하기 위해
- Node.js 와 Express 차이
- Node.js는 Chrome의 V8 자바 스크립트 엔진을 기반으로하는 자바 스크립트 런타임환경
- node.js의 원리와 방법을 사용하여 웹 애플리케이션을 개발하기위한 node.js 기반 프레임 워크.
- Node는 소프트웨어를 쉽게 작성할 수 있는 라이브러리가있는 Javascript 환경 -> Express는 웹 서버를 쉽게 작성할 수 있도록 Node.js 확장한 프레임워크 (node.js 만 사용하는 것보다 API 요청 및 서버 관리를보다 쉽게 처리 할 수 있음)
- Node.js의 HTTP모듈을 이용하여 서버를 구성할 수 있지만 라우터나 미들웨어를 관리하기에 까다롭다. 이런 부분을 편하게 해주는게 Express
- 세팅한것
- 절대경로/Alias
- Prettier/Eslint
- Codegen
-
- Javascript vs React 렌더링
- React는 가상돔을 만들어서 가상돔끼리 비교해 DOM 트리의 다른 부분만을 리렌더링
- Javascript는 트리 전체를 다시 그리기 때문에 매우 비효율적
Uber C트랙 질문
- 하나의 요청에 대해 여러 명의 드라이버가 동시에 수락하면 어떻게되나요?
- 먼저 요청한 드라이버가 매칭이 되고, 이 후에 요청을 수락한 드라이버에게는 이미 매칭된 요청이라는 알림 메세지가 표시되도록 구현되어있습니다.
- NoSQL은 정합성을 보장하지 않기 때문에 이러한 방법으로는 100% 보장할 수 없을 것 같은데 다른 해결책을 고려해보셨나요? -> redis를 이용하거나 transaction을 이용하여 해결할 생각입니다.
- 매칭한 후에 탑승자와 드라이버 모두 화면에서 나가버리면 상대가 더 이상 변경되지 않을 것 같은데 어떻게 처리하셨나요?
- 이 부분에 대해서 팀원들과 많은 얘기를 해보았습니다. 특정 시간이 지나면 자동으로 운행이 종료되는 방법도 생각을 해보았지만 결국 드라이버가 새로운 요청을 받기위해선 운행종료를 해야하기 때문에 이러한 상황은 거의 일어나지 않을 것이라 생각하였고, 또한 예상보다 운행종료 시간이 늦어진다고 임의적으로 운행을 종료한다면 마찬가지로 운행이 종료되지 않았는데 왜 자동으로 운행이 종료되었냐는 등 또 다른 문제가 발생할 것이라 생각했기 때문에 이 부분에 대한 처리는 따로 하지 않았습니다.
- 최대 몇 명의 운전자에게 요청이 가나요?
- 요청을 보낸 사용자 기준 반경 10km내의 드라이버에게 요청이 가도록 했습니다.
- 서버쪽 GraphQL과 DB는 어떤 걸 사용하셨나요?
- Apollo server와 MongoDB 사용했습니다.
- mongoDB 사용한 이유를 알 수 있을까요?
- MongoDB에서는 다양한 위치 정보 쿼리 기능을 제공하기 때문에 위치를 기반으로 많은 기능이 제공되는 저희 서비스에 어울린다고 생각했습니다.
- 또한 실시간으로 많은 데이터를 보여줘야 하기 때문에 읽기 기능이 빠른 mongoDB를 사용했습니다.
가계부 c팀
- 개발하면서 신경 쓴 부분
- express를 사용한 이유
- 주제 선정 어떻게 했는지
- 처음에 여러 주제에 대해서 설문조사를 작성했는데 우리 팀원분들은 모두 일순위로 투표한 주제를 진행하게 되었습니다.
실시간 예약 A팀
- 티켓팅의 특성상 동시간에 많은 유저가 몰릴텐데 이에 대해 대응하신게 있는지
- 소켓 성능 이슈에 대한 더 자세한 설명
- Apollo GraphQl를 선택한 이유
- 가장 어려웠거나 학습하면서 기억에 남는 내용
- hooks를 사용했는지? 했다면 적용 비율은?
- ApolloClient가 있어서 리덕스를 쓸 이유가 없을텐데 쓴 이유가 있을까요?
- redux와 훅스, 아폴로 각각 상태관리 역할이 어떻게 나눠지나요?
푸파고
- 렌더링 오버헤드가 react에서도 있었겠지만 지도를 그리는 그래픽스 부분에서도 꽤 있을 것 같은데, react 최적화가 전체적으로 얼마나 성능을 개선했나요?
- mongodb 동시성 문제에 대해 샤딩을 통한 동시성 문제의 경우도 생각해 봤나요?
영상 편집기 WAVE
- 팀원끼리 룰은 어떻게 나눠서 작업했나요??
- pr과 issue에 대한 컨벤션을 미리 정한 후 백로그를 통해서 진행해야 할 작업들을 먼저 작성
- 후에 밸런스를 맞춰가면서 각 팀원들이 개발할 작업을 선택.
- 일주일 간 할 작업을 매주 월요일에 팀원들과 나누고 작업 시작 전 github 이슈에 등록하여 어떤 작업을 진행하고 있는지 알 수 있도록 함
- pr도 하나의 기능이라도 최대한 작게 나눠서 팀원들이 코드를 이해하는데 어려움이 없도록 했습니다.
- 작업을 그날그날 선택하지 않고 미리 선택함으로써 다른 사람의 작업을 이어서 해야할 경우 그 동안 다른 작업을 먼저 시작.
- 작업을 선택할 때는 하나의 기능을 한 사람을 전체로 맡지 않고 서로 섞이도록 선택.
트위터
- 깊게 봤던 부분이 어떤 부분인지.
-
-