처음으로 웹을 접하다

Gunjoo Ahn·2022년 11월 21일
0

회고

목록 보기
1/11
post-thumbnail
post-custom-banner

신입 프로젝트 - 실시간 채팅 시스템

약 2년전 처음으로 회사에 입사했을 때의 이야기이다. 머신러닝 시스템 연구실을 졸업하고, 그 당시에 원했던 업무는 MLOps였다. 물론 웹에 대해서는 정말 백지장이었다.

그렇게 회사 인사팀에 어떤 팀에 가고 싶냐 했을 때, ML을 할 수 있는 백엔드 팀이라 말했고, 어떤 팀에 소속되게 되었다. 그런데 막상 합류한 팀에서 당장 필요했던건 그냥 CRUD라도 할 줄 아는 백엔드였고, 당시 팀에서 선택되었던 기술 스택은 JavaScript와 NodeJS였다.

그렇게 시작하게된 신입에게 주어진 첫 교육용 NodeJS 신입 프로젝트는 실시간 채팅 프로그램이었다. 프론트엔드 팀원과 둘이 팀을 맺고 한달간 JavaScript + NodeJS 학습을 진행하고, DB + API 설계를 한 이후 발표를 하였다. 이 때 처음으로 RESTful에 대하여 접했고, 협업하여 웹 프로젝트를 진행해 본 것이다.

지금 돌이켜보면 학습으로 꽤나 괜찮았던 신입 프로젝트였는데, 문제는 코드 리뷰를 전혀 해주지 않았다. 그래도 결과 발표 당시에 API 설계 피드백이나 DB 설계 피드백은 받았었다. 그 때는 promise, async, await도 제대로 이해하지 못해, 3중 4중 콜백 지옥의 아주 난잡한 JavaScript 코드에 추상화가 거의 없는 통짜 Request, Response 함수를 작성했었다. 학습만을 위한 코드여서 정리가 전혀 안되어있어 Github private 레포에 고이 묻어 두고 있다.

코드 자체를 리팩토링하기에는 오래걸릴 것같으니 건드리지 않고 ReadMe 작성부터 주석이나 indentation 등 코드 외적으로 읽기만 좋게 수정한 이후에 레포를 새로 파서 공개할까 한다. 아마 어디서든 테스트하기 좋게 Docker에 올리는 것까지는 추가 할까 싶다.

작성한 조금 창피한 4중 콜백 코드 예시

//TODO need to change callback chain to async await
const createRoomRoute = function (req, res) {
 console.log('/rooms 라우팅 함수 호출')

 var paramId = req.body.userId || req.query.userId
 var paramRoomName = req.body.roomName || req.query.roomName

 queries.getRoombyRoomName(paramRoomName, paramId, function (err, results) {
    if (err) {
      console.log('create room route err 1')
      return res.json({
        type: 'err',
        message: 'getting room with id was failed',
      })
    }
    if (results.length > 0) {
      return res.json({
        type: 'info',
        message: 'already same room exists',
      })
    }

    queries.createRoomWithUserId(paramRoomName, paramId, function (err, results) {
      if (err) {
        console.log('create room route err 2')
        return res.json({
          type: 'err',
          message: 'create room fail',
        })
      }

      queries.getRoombyRoomName(paramRoomName, paramId, function (err, results) {
        if (err) {
          console.log('create room route err 3')
          return res.json({
            type: 'err',
            message: 'getting room with id was failed - 2',
          })
        }

        if (results.length < 1) {
          return res.json({
            type: 'info',
            message: 'room not created',
          })
        }

        queries.joinRoomWithUserId(results[0].room_id, paramId, function (err, join_results) {
          if (err) {
            console.log('create room route err 4')
            return res.json({
              type: 'err',
              message: 'join room with id was failed',
            })
          }

          userSocket = people.paramId
          console.log('online status')
          console.dir(people)
          if (userSocket) {
            console.log(paramId + ' create and join in room' + rooms[0].room_name)
            userSocket.join(results[0].room_id + '')
          } else {
            console.log('create success but join fail - no user socket')
          }
          console.log(results[0])
          return res.send(results[0])
        })
      })
    })
  })
}

기술 스택

NodeJS, Express, MySQL, Redis, Passport, Socket.IO를 사용하였다. ORM을 몰라서 아래처럼 쌩 SQL을 때려 박았다. 처음에 프론트 팀원의 코드가 준비되지 않았을 때, 다른 실시간 채팅 웹 Application을 가져와 테스트하느라 EJS를 살짝 사용했었다.

Redis를 사용한 이유는 세션 정보를 저장해 일시적인 서버 다운에 대비하기 위함이었다.
코드 수정 이후 재실행하면 계속 세션 정보가 사라져 매번 로그인하는 것을 하지 않기 위해 적용했었다.
connect-redis 패키지로 큰 설정 없이 간단하게 적용하였다.

Convention

없다. 오랜만에 private 레포를 열었는데 빵 터졌다. 커밋이 정말 "업로드하려는데 커밋하라네? 귀찮다" 라는 생각으로 커밋한 것이 보인다.

ERD


친구 초대 기능이 있어, 친구 관계 테이블을 N:M으로 설정하였다.
누가 어떤 채팅방에서 남긴 메시지인지 chatting_message 테이블에 저장한다.

API 설계

나름 RESTful하게 설계하려고 노력했던 것같다. 중간에 camel case에서 snake case가 중구난방으로 섞여있는데, 아래와 같은 것이 언급되어있는 것을 보니 당시에 아마 camel case에서 snake case로 바꾸자는 이야기가 있었는데 전부 못바꾸었던 것으로 보인다.

돌아보며

처음으로 회사에 취직하여 웹 개발이란 것을 처음 접하고 학습하고 팀으로 진행했던 프로젝트였기에 기억에 남는 프로젝트이다. 비록 한달도 안되는 짧은 프로젝트였지만, 머신러닝 시스템밖에 모르던 우물안 개구리를 웹의 세계로 이끌었다. 그리고 설계하고, 개발하고, 협업하는 재미를 알려준 고마운 프로젝트이다.

profile
Backend Developer
post-custom-banner

0개의 댓글