이 레포지토리는 원티드 프리온보딩 백엔드 코스 3차 과제를 위해 만들어졌습니다.
- 일정 : 2021년 11월 8일(월) 오후 6시 ~ 11월 10일(수) 오전 10시
팀장 박상수 | 팀원 김성연 | 팀원 최준호 |
---|---|---|
blog: Plus Ultra github: epitone |
blog: sudocorp github: SibaDoge1 |
blog: raejun92.log github: raejun92 |
실시간 저장 소켓 이벤트 | 실시간 저장 소켓 이벤트, DevOps | 퍼블리싱 관련 DB / API |
프로젝트 회고 | 프로젝트 회고 | 프로젝트 회고 |
팀원 어유선 | 팀원 김현길 | 팀원 이동훈 |
---|---|---|
blog: Makkiato github: Makkiato |
blog: gusrlf14 github: hyunghilkim |
blog: dongjay00.log github: dongjay00 |
프로젝트 관련 DB / API | 프로젝트 관련 DB | 퍼블리싱 관련 DB / API |
프로젝트 회고 | 프로젝트 회고 | 프로젝트 회고 |
- Swagger나 Postman을 이용하여 API 테스트 가능하도록 구현
- README 작성
- 프로젝트 빌드, 자세한 실행 방법 명시
- 구현 방법과 이유에 대한 간략한 설명
- 완료된 시스템이 배포된 서버의 주소
- Swagger나 Postman을 통한 API 테스트할때 필요한 상세 방법
- 해당 과제를 진행하면서 회고 내용 블로그 포스팅
- 회원가입
- 게임 제작하기
- 제작 중 단계의 게임을 '프로젝트'
- 프로젝트는 "실시간"으로 반영
- 게임 출시하기
- 프로젝트 당 퍼블리싱 할 수 있는 개수는 하나입니다. 퍼블리싱한 게임은 수정할 수 있어야 하며, 수정 후 재출시시 기존에 퍼블리싱된 게임도 수정
- 출시하는 게임은 다른 사용자들도 볼 수 있으며, 사용자들의 조회수 / 좋아요 등을 기록 가능
- 게임 혹은 사용자 검색'을 통해서 찾기 가능
- Node.js, express, MongoDB, Mongoose, socket.io를 활용해서 CRUD API, 회원가입 로그인 API, 프로젝트 API, 퍼블리싱 API, 실시간 이벤트 처리를 구현했습니다.
- 인증, 인가를 위해 세션, 쿠키를 활용했습니다.
- 코드 컨벤션, 커밋 컨벤션, Git Flow를 지켜가며 작업했습니다.
- Github Project, 마일스톤을 활용해서 백로그, 이슈 관리를 진행했습니다.
- 계층 분리를 통해 코드의 가독성을 높였습니다.
- 리팩토링을 통해 가독성을 높이고, 유지보수를 편하게 하기 위해 노력 했습니다.
- 인증방식은 JWT를 쿠키에 저장하는 방식으로 구현 하였습니다.
- 프로젝트 당 배포 할수 있는 개수는 하나로 구현하고, 배포한 게임은 수정 가능, 수정 후 재배포시 기존 배포된 프로젝트도 수정 가능하게 기능 구현 하였습니다.
- 게임(프로젝트명) 또는 사용자를 키워드로 하여 검색이 가능하게 기능 구현 하였습니다.
- 자바스크립트 자체 내장 Error 클래스를 상속 받아서, 커스텀 에러를 생성해서 관리했습니다.
- 기존의 RestFul Api 설계의 경우, 실시간 저장이라는 개념이 성립할 수 없었습니다. 어쩔 수 없이 게임을 제작하는 사용자부분은 브라우저 를 이용한 가상의 게임제작 페이지를 사용하기로 하였습니다.
- socket.io를 이용하여 서버와 클라이언트간의 실시간 연결을 유지하고, 게임 프로젝트 데이터의 변경 시 데이터를 서버에 저장합니다.
-
처음에는 일정 시간 단위로 단순히 데이터를 보내는 것을 생각했지만, 단위가 길어지면 실시간 저장이 힘들고 짧아지면 너무 빈번한 저장으로 성능에 좋지 않다고 생각했습니다.
-
그렇다고 사용자가 데이터를 변경할 때마다 요청한다면 1초에 수십번의 요청 및 쿼리실행이 될 것이라 생각하여 개선방안을 생각해보았습니다.
-
1차적으로, 서버에 버퍼를 두는 방식을 생각했습니다. 클라이언트가 저장요청을 보내면 서버는 해당 데이터를 버퍼에 임시보관하고, 일정 시간 뒤 버퍼의 최신 데이터를 DB에 저장하도록 했습니다.
-
이를 통해 어느정도의 성능개선을 기대할 수 있었지만, 클라이언트에서의 많은 요청은 여전히 존재했습니다.
-
이 문제를 개선하기 위해 클라이언트에서도 저장요청에 CoolTime을 구현하기로 했습니다.
- isCoolTime 변수와 setTimeout을 이용해, 정보를 여러번 변경하더라도 1초 뒤에 하나의 요청만 하도록 변경하였습니다.
- 그 결과 이전과 똑같은 방법으로 테스트했을 때, 90번에 달하는 저장 요청이 9번의 버퍼저장과 4번의 DB쿼리 실행으로 줄어들었음에도 실시간 저장이 가능해졌습니다.
- 레포지토리를 clone 받거나, 압축을 해제한 후 npm install을 통해 환경 셋팅을 진행합니다.
- npm start를 통해 서버를 구동합니다.
- src 폴더에 .env 파일을 설정해서, 환경변수를 설정합니다.
- npm start로 서버를 구동시키고, npm test를 입력하면 단위 테스트가 가능합니다.
- .env설정 노션 링크
-
링크 접속불가 시 .env 파일 설정 방법
MONGO_URL= 'db 주소' PORT= '서버의 포트' JWT_SECERT= '원하는 시크릿코드' JWT_ALGO="HS256"
-
-
Postman을 활용하여 API 작동 테스트를 진행했습니다.
-
배포된 서버 주소 및 자세한 API 명세는 아래에서 확인 가능합니다.
-
을 클릭하여 웹브라우저 혹은 Postman 클라이언트에 콜렉션이 로드되면
- Variables 탭에서 서버 Host와 Port를 지정합니다. (기본값이 지정되어 있습니다.
- Variables 탭에서 테스트하는 동안 사용할 username과 password 그리고 newProjectName을 지정합니다. (기본값이 지정되어 있습니다.)
- 그후 우측 상단의 Run 버튼을 눌러 RUN ORDER 화면에 진입한 뒤 Run [Collection Name]을 클릭하면, 이상적인 상황에서의 테스트가 진행됩니다.
- 좌측의 Workspace 화면에서 해당 콜렉션과 그 요청에는 여러 이상적이지 않은 상황의 테스트에 대한 예시가 있습니다.
**유의사항** *일부 요청의 경우 JWT를 필요로합니다. JWT는 로그인 과정에서 "Set-Cookie" 헤더를 통해 클라이언트가 스스로 관리하게끔 전달됩니다. *프로젝트 등록 과정에서 콜렉션 Variable의 projectId를 자동으로 수정합니다. 이를 원치 않는다면 해당 요청의 Test Script에서 지워주세요
-
게임 제작의 경우 다음과 같은 과정으로 브라우저를 이용 하여 확인 가능합니다.
-
테스트 하기 전, api요청을 통해 프로젝트를 생성하고 프로젝트Id를 알고있어야 합니다.
- 테스트를 위하여, .env설정 노션 링크에 예시용 정보 및 주소를 적어놓았습니다.
-
아래 주소로 접속하여 로그인을 합니다.
- 로그인 페이지 http://{{서버 주소}}/user/token
-
아래 주소로 접속하여 게임제작 및 퍼블리시를 테스트합니다.
- 게임제작 페이지 http://{{서버 주소}}/projects/my/{{프로젝트Id}}?username={{유저네임}}
-
📦src
┣ 📂bin
┃ ┗ 📜www.js
┣ 📂configs
┃ ┣ 📜db.js
┃ ┣ 📜index.js
┃ ┗ 📜secretKey.js
┣ 📂controllers
┃ ┣ 📜gameController.js
┃ ┣ 📜projectController.js
┃ ┗ 📜userController.js
┣ 📂globals
┃ ┣ 📜index.js
┃ ┣ 📜responseMessage.js
┃ ┣ 📜routes.js
┃ ┗ 📜statusCode.js
┣ 📂libs
┃ ┣ 📜encryption.js
┃ ┣ 📜jwt.js
┃ ┗ 📜serverSocket.js
┣ 📂middlewares
┃ ┗ 📜auth.js
┣ 📂models
┃ ┣ 📜index.js
┃ ┣ 📜likeModel.js
┃ ┣ 📜projectModel.js
┃ ┣ 📜releaseModel.js
┃ ┗ 📜userModel.js
┣ 📂public
┃ ┣ 📂js
┃ ┃ ┗ 📜clientSocket.js
┃ ┗ 📜gameEditor.html
┣ 📂routes
┃ ┣ 📜gameRouter.js
┃ ┣ 📜globalRouter.js
┃ ┣ 📜index.js
┃ ┣ 📜projectRouter.js
┃ ┣ 📜tokenRouter.js
┃ ┗ 📜userRouter.js
┣ 📂services
┃ ┣ 📜gameService.js
┃ ┣ 📜projectService.js
┃ ┗ 📜userService.js
┣ 📂utils
┃ ┣ 📂db
┃ ┃ ┗ 📜index.js
┃ ┣ 📂errors
┃ ┃ ┣ 📜commonError.js
┃ ┃ ┣ 📜errors.js
┃ ┃ ┣ 📜gameError.js
┃ ┃ ┗ 📜userError.js
┃ ┣ 📜index.js
┃ ┣ 📜logger.js
┃ ┗ 📜resFormatter.js
┣ 📜.env
┣ 📜.eslintrc.json
┣ 📜.gitignore
┣ 📜.prettierrc.json
┣ 📜app.js
┣ 📜package-lock.json
┗ 📜package.json