공약쥬스 개발기
공약쥬스 서비스를 개발하면서 배우고 느낀 점을 정리해 본다.
사이드 프로젝트
공약쥬스는 다들 직업을 가지고 있는 이들이 콘텐츠, 마케팅, 디자인, 기획 등의 역할을 맡아 퇴근 후 혹은 주말에 조금씩 시간을 내서 만든 사이드 프로젝트이다.
지지정당이 없거나 처음 선거권이 주어진 사람들을 위한 서비스를 만들어보자는 뜻을 모아 시작했다.
나는 초기 기획 단계였던 1월에 합류하여 서버개발을 맡았다. 작업 후반부에는 프론트엔드 쪽도 일부 넘겨 받아서 작업을 했다.
나는 원래 사람들이 가진 정치혐오를 없애고 싶다는 생각을 자주 했다. 우리가 만드는 서비스가 그렇게 할 수 있다고 생각했다.
또, 개발자로 사이드 프로젝트를 하면서 지금껏 접해보지 못했거나 제대로 사용하지 못한 기술을 사용해보고 싶었다.
결론적으로 보면, 나는 기술 면에서도 크게 성장했고 서비스도 12만명 이상의 사용자를 모으면서 꽤나 성공을 거두었다.
사람들이 올리는 후기를 보면서 큰 보람을 느꼈다.
사용한 기술
서버는 Express.js와 TypeScript를 이용해 개발했고, 데이터베이스는 MySQL을 사용했다.
원래 회사에서도 express 코드는 계속 만지고 있었고, MySQL도 꾸준히 사용하고 있었던지라 어려움은 크게 없었다.
다만 express를 0부터 서비스 레벨까지 만들어본 것은 처음이었던지라 문서를 읽어가면서 하나하나 썼다.
express-rate-limit, cors, morgan, greenlock, express-async-handler 등 서버를 개발하며 필요한 부분이 생길 때 그에 맞는 라이브러리를 설정해가는 재미도 있었다.
TypeScript는 공부해본 적은 있었지만 실제 사용해보는 것은 처음이었다. 타입이 있는 개발을 하니 정말 정말 좋았다. 타입을 먼저 선언하고, 이에 맞춰서 코드를 수정해나갈 수 있으니 헷갈릴 일이 없었다.
클라우드는 AWS EC2와 RDS를 사용했다. 서버비가 많이 나올까봐 굉장히 걱정했고 그걸 생각해서 여러 장치를 고민했는데, 결론적으로는 기우였다. 22만 명이 넘는 사용자가 접속했음에도 아직 프리티어를 넘어서지 않았다.(ㅎㅎ) 그래도 pm2 log가 안보일 정도로 빠르게 쌓이는 것을 구경할 수 있어 성공적이었다고 생각한다.
작업하면서 크게 고민했던 부분은 아래와 같다.
- DB 설계를 어떻게 해야 할까
- 디도스 등 공격이 들어오거나 해킹이 발생하면 어떡하지
- 동시접속자가 너무 많아서 느리면 어떡하지
1번 DB 설계는, 기획이 완벽하지 않은 상태에서 작업을 시작하려고 해서 고민이었다.
가령, 정당과 공약의 관계가 1:다일지, 아니면 다:다일지는 공약을 확인해봐야 알 수 있는 상황이었다.
일단 다:다로 설계한 후 이에 맞게 코드를 작성했다.
회사에서는 사용하지 않았던 외래키도 설정을 해줬다. 저장해야 하는 데이터가 그렇게 많지 않은 상황이었기 때문에 최대한 정규화를 하여 DB를 설계했고, 대신 FK를 달아두었다.
이후 코드 상에서는 transaction 처리까지 해두어서 데이터의 정합성에 문제가 생기지 않도록 했다.
2번은 꽤 중요한 문제였다. 우리 서비스는 가입 절차가 없다. (선거 결과를 저장하는데, 개인정보를 저장하는 것이 사용자 입장에서 맞지 않았다. 물론, 번거로운 절차를 거쳐야 한다는 것도 있었다.) 따라서 인증을 통하여 제한을 두기가 어려웠다.
그래서 생각해본 것은 토큰 발행이었다. 딱히 인증과 상관은 없지만, 무조건 결과를 보낼 수 없도록 하나의 장벽을 더 둔 것이었다. 사이트에 접속하면 토큰을 발행하여 브라우저에 보냈다가 공약을 선택한 후에 결과를 제출할 때 해당 토큰이 DB에 존재하는지를 확인하는 방식이었다.
토큰 발급 후 바로 제출할 수 없도록 시간 차를 두었다.
CORS도 설정하기는 했는데, 어차피 server-to-server로 요청을 마구 보내면 데이터가 오염될 수밖에 없다.
만약에 네트워크 탭을 보고 이러한 로직을 발견했다면 해킹하는 것은 어려운 일도 아니었겠지만, 어쨌든 무엇이라도 장벽을 하나 더 두려고 생각해 낸 방식이다.
PM2 log를 모니터링한 바로는, 이상한 시도는 없었던 것으로 보인다.
동일한 IP 주소에서 연속하여 요청이 들어오면 막는 라이브러리 express-rate-limit를 사용했다. 간편하게 설정할 수 있었다.
3번은 결론적으로 말하자면 사실 고려할 필요가 크게 없는 부분이었다.
지금 내가 다니는 회사는 엄청나게 많은 트래픽을 다루고 있으며 속도 또한 매우 중요한 회사이다. 그래서 사이드 프로젝트를 하면서도 계속 트래픽과 속도를 고민하는 내 자신을 발견했다.
그런데 우리 서비스는 보름 간 최대 100만명이 들어온다고 해도, 데이터가 크게 오가는 서비스가 아니기 때문에 그다지 고민할 부분은 아니었다.
사람에게 친절한 코드, 기계에게 친절한 코드가 있다고 하면, 이번 사이드 프로젝트에서는 전자를 선택했다.
가장 접속자가 많았을 때, 초당 4-5건의 DB 쓰기가 발생하기도 했는데, 이 정도로는 프리티어로 해결 가능한 수준이었다.
그럼에도 고민한 부분이 있다면, 굳이 static한 정보가 필요할 때 (ex. 정당이름, 공약 내용 등) 꼭 DB에 접속을 해야하는지 정도였다.
이외에도 key가 변하는 interface를 어떻게 타입 지정해야 하는지라던가, https 인증서 설정 방법이라던가, RESTful하게 API를 설계하는 방법이라던가 하는 사소한 고민도 많았다.
좋았던 점
사이드 프로젝트의 묘미를 느꼈다. 하고 싶은 일을 하고, 쓰고 싶던 기술을 쓰고, 거기에 사용자 피드백이 바로바로 눈에 보이니 의욕이 마구 샘솟았다.
특히 서비스를 시작하면서부터 굉장히 신이 났던 것 같다. 동시 접속자 수가 400명을 넘을 때도 있었고, 긍정적인 피드백이 꽤 이어졌다. 돈을 벌지 않는 일에서도 이렇게 보람을 느끼는구나 생각했다.
사람들 간에 합이 잘 맞았다. 고민되는 부분을 상의할 수 있는 개발동료와도 잘 맞았고, 기획 상 우려되는 부분을 함께 나눌 수 있는 좋은 동료가 있었다.
해야할 게 많고, 시간이 부족한 순간이 있었다. 그때 같이 일하던 사람들이 '재미있자고 하는 건데, 너무 스트레스 받지 마시라'고 이야기를 해주었다. 돌이켜보면 정말 고마운 말이다.
아쉬운 점
시간이 부족했던 것이 아쉽다. 가장 중요한 부분인 10대 공약이 늦게 발표되는 것이 꽤나 걸림돌이었다. 각 정당의 10대 공약은 3월 중순이 넘어서야 선관위 홈페이지에 게재된다. 해당 공약을 분류하고, 거기에 맞는 이슈를 고민하고, 문구를 수정하고, 기획 상 수정할 부분은 없을지 고민했다.
원래는 3월 막날에 오픈하는 것이 목표였으나, 4월 첫째주로 미뤄졌다. 사전투표 일정을 고려하면 부족한 부분이 있을지라도 4월 초에는 꼭 오픈을 해야 했다. 개발팀은 물론이고, 콘텐츠, 디자인, 마케팅 모두 회사를 휴가내고 일을 해야 했다. 약간 무리를 했다.
또, 코드리뷰할 시간도 없이 master에 계속 push를 한 것도 아쉽다. 재사용하거나 규모를 더 키워나갈 서비스는 아니었으니까 어쩔 수 없지만, 다음에는 꼭 서비스하게 되는 코드는 리뷰를 받는 절차를 거치려고 한다.
시간이 부족한 만큼, lean했으면 더 좋았을 것 같다는 생각도 든다. 기획-디자인-개발의 사이클이 폭포수처럼 이어졌다. 돌아가는 서비스를 작게라도 만들어서 공유했을 때, 사람들이 의욕을 가지게 되고 또 아이디어를 가지게 되는 것 같다. 그래서 다음에는 꼭 스프린트 단위로 작게 쪼개어 완성해 나가고 싶다.
물론, 데드라인이 너무나도 명확한 선거라는 주제를 가졌기 때문에, 기한 내에 완성을 할 수 있었던 것 같기도 하다. (Deadline-driven Development...)
그리고 조금만 더 개선하면 좋을 부분이 눈에 계속 보이는데, 체력과 시간의 한계로 더 업데이트를 못해서 아쉬웠다.
앞으로의 계획
지금까지 공부한 것을 바탕으로 조금 더 깊게 들어가보고 싶다. 궁금한 것이 더 많아졌다.
또, 사이드 프로젝트를 꾸준히 해나가고 싶다.