본문 바로가기

토이 프로젝트

채팅 애플리케이션 만들기 - v1.0

새로운 기술을 공부하는 방식으로는 크게 두 가지가 있다고 생각합니다. 하나는 문서를 처음부터 읽으며 개념을 학습하는 교과서 정독형이고 다른 하나는 일단 직접 구현해 보며 학습하는 실용형입니다.

평소의 저는 교과서 정독형에 더 가깝다고 생각하지만 그동안 관심 있던 여러 기술들을 입문(체험)해보는 목적으로 실용형 간단한 채팅 애플리케이션(v1.0)을 만들어 보았습니다.

 

 

버전

v2.0 2024. 04 - 전반적인 기능 개선

v3.0 2024. 08 - 도메인 모델링 기반 리팩토링

모든 소스코드는 Github에서 확인 가능합니다.

 

요구사항 분석

이 애플리케이션의 MVP 기능 요구사항은 아래와 같습니다. 

1. 유저는 로그인을 할 수 있다. 존재하지 않는 닉네임이면 회원가입으로 취급한다.
2. 유저는 방을 생성/참여할 수 있다.
   - 방에 속한 유저가 방의 고유 키(roomId)를 공유하고 타 유저는 이 키를 입력하여 참여한다.
   - 한 방에 접속 가능한 인원은 최대 20명으로 한다.
3. 유저는 자신이 참여중인 방 리스트를 가지고 있는다.
   - 방 리스트 중 하나를 선택한다. 기존 채팅 메시지를 모두 가져온다.
4. 유저는 선택된 방에서 채팅을 입력할 수 있다. 나 이외의 상대방 채팅은 모두 왼편에, 내 채팅은 오른편에 표기된다.

 

구현 기술 선택

1. React

이 프로젝트의 가장 큰 목적 중 하나입니다. 제 실무 환경에서 웹 프론트엔드는 모두 React로 만들어지는데, 백엔드 개발자로서 그동안 React 관련 코드를 이해하지 못했습니다. 그래서 웹 페이지상의 오류 현상만을 가지고 디버깅할 땐 많은 시간이 소요되곤 했습니다. 그리하여 이번 프로젝트 목표를 'React 코드를 읽고 해석할 수 있는 수준이 되기'로 정했습니다. 이것이 프론트엔드 영역에 사용가능한 기술이 다양함에도, React를 선택한 가장 큰 이유였습니다. 퍼블리싱과 초기 React 컴포넌트 구조 설계는 동료 개발자분께서 도움주셨습니다. 이후에는 온전히 제 힘으로 API연결 등을 할 생각이었지만... 한 번에 익숙하지 않은 여러 개념들을 경험하다 보니 산으로 가는 것 같은 느낌이 들어서, 결국 중간에 동료 개발자분께 리뷰받았습니다. 잘 리뷰해 주셔서 감사합니다.

 

2. NestJs vs Spring

백엔드 프레임워크는 빠른 프로토타입 개발 목적 하나로 NestJs를 선택하였습니다.

 

3. REST API vs graphQL

이 프로젝트의 두번째 목적입니다. graphQL@Subscription 으로 양방향 소켓 통신을 경험해보고자 하였습니다.

그렇기 때문에 REST vs graphQL 장단점 비교 같은 문서에서, '클라이언트-서버의 통신 횟수를 줄이고 원하는 유연한 응답을 받을 수 있'다 등등의 내용과는 무관하게 통신 방식을 graphQL로 선택하였습니다. 같은 이유로 프로젝트의 주제도 실시간 채팅으로 하였습니다.

 

4. RDBMS vs MongoDB

RDBMS은 익숙하고, MongoDB 는 경험해본 적이 없지만 이 프로젝트에서는 MongoDB 가 적합하다고 판단하였습니다.

테이블을 정의하고, 테이블의 관계를 설정하고, 제약조건을 걸고, 조인을 통해 데이터를 가져오는 RDBMS과 다르게 MongoDB는 데이터의 중복을 인정하고 문서단위로 저장하여 문서를 보여주기만 하면 됩니다. 예를 들어 채팅방 내 메시지는 유저의 닉네임과 함께 보여져야 합니다. 기존의 RDBMS방식으로 설계했다면 메시지 테이블에는 roomId와 userId를 외래키로 갖게 설계할 수 있습니다. 특정 채팅방의 메시지 목록을 조회하기 위해 roomId는 where 조건절에, userId는 테이블 join으로 nickname을 가져와야 합니다.

MongoDB에서는 message 문서에서 필요한 user 정보를 객체로 저장할 수 있습니다. userId, nickname을 모두 저장하고 읽을 땐 다른 문서를 참조하지 않고 message 문서의 roomId만 필터 하여 조회하게 됩니다.

 

5. 나머지 기술

 

redis(pubsub)

메시지 브로커로서 동작합니다. 이미 처음 접하는 기술들이 많았기 때문에 다른 구현체는 고려하지 않고 이미 경험해 본 redis를 선택하였습니다. 또한 방 하나에 최대 인원이 20명으로 구독-발행 모델로 메시지를 팬아웃하도록 설계하였습니다.

 

mongo-express

mongoDB GUI 클라이언트입니다. 문서들이 정상적으로 삽입되었는지 등을 조회하기 위해 도입하였습니다.

 

docker(docker-compose)

모든 프로세스를 컨테이너 화하여 격리시키고 네트워크를 구성하여 서로 통신 가능하게 하였습니다. 이 애플리케이션을 명령어 한 줄로 실행시키고자 합니다.

docker-compose up -d

 

v1.0 개발 범위에서 제외된 내용

'토이프로젝트'라는 컨셉이나 이 프로젝트에 주어진 시간을 고려하여 일부 기능들은 다음 버전으로 미루거나 제외하였습니다.

기준은 매우 이상적인 요청 시에 필요한 기능이 아니면 대상에 포함시켰습니다.

 

1. 에러핸들링

  - v1.0 에서는 에러처리가 안되어있습니다. 자연스러운 에러를 나타내기 위해 스낵바 같은 React의 추가적인 작업이 요구되어 추후 개선으로 남겨두었습니다.

2. 로그인

  - v1.0 에서는 닉네임만 입력하여 유저를 식별합니다. 이 닉네임으로 userId를 리턴 받아 브라우저 local storage에 저장하여 인증 토큰처럼 사용됩니다.

  - 유저 식별이 필요한 요청 시에 Authorization 헤더에 userId를 넣는 것이 아닌, 파라미터로 graphql의 input으로 넣게 됩니다.

  - 이 프로젝트는 local 환경에서 동작하는 애플리케이션이므로 다른 이유가 없다면 수정하지 않을 예정입니다.

3. MongoDB 트랜잭션

  - 현재 MongoDB 백엔드 로직은 모두 트랜잭션처리가 안되어있습니다. 추후 개선으로 남겨두었습니다.

 

서비스 아키텍처

회고

클라이언트와 서버가 나누어 개발하는 요즘 세대 개발자들(=작성자...)은 굳이 노력하지 않는다면 업무 외 경험 기회가 많지 않습니다. 효율적인 백엔드 로직을 작성하기 위해 도메인에 대한 고민과 소통은 자주 했지만, 정작 프론트엔드와 API 설계 및 연동에서의 소통은 수동적으로 했던 점을 반성하며 이 프로젝트를 시작했습니다.

'React 프로젝트 코드를 읽을 수준이 되기', 'graphQL subscription 구성해 보기' 2개의 목적으로 프로젝트의 주제를 정하고 그에 맞는 나머지 기술스택을 선택하여 빠르게 개발할 수 있었습니다. 더 많은 기능과 더 단단한 설계를 하고 싶은 마음을 제어하는데(마세라티 문제) 결단이 필요했습니다. 여러 가지 측면에서 아직 부족함이 많은 애플리케이션임은 분명하지만, 제 목표는 달성했기 때문에 추후 이 프로젝트로 새로운 목적이 생기면 개선할 기회를 갖도록 하겠습니다.

 

<2024. 04. 추가>
v2.0이 릴리즈 되었습니다. 전반적인 개선을 하였습니다.링크

'토이 프로젝트' 카테고리의 다른 글

채팅 애플리케이션 만들기 - v2.0  (0) 2024.04.03