저번주와 이번주 주말엔 여러 일들이 있어서, 이번에도 회고를 한 주 미뤄서 쓰게 되었다. 본의아니게 자꾸 회고를 미뤄서 하는 느낌이라 슬프다..

두번째 프로젝트지만, 첫 프로젝트 공개!

멤버쉽부터는 이제 내가 만든 프로젝트를 공개할 수 있게 되었다. 그래서 이번에는 깃헙 페이지를 활용해서 프론트로나마 내 프로젝트를 볼 수 있도록 해봤는데, 그 페이지가 바로 이거다. 소스코드도 Repository에 공개는 되어있지만 정말 못나게 짜서 꼭 새로 탈바꿈 해줄 생각이다. 백엔드 코드는 백엔드와 프론트가 아직 제대로 연동이 되어있질 않아서, 좀 더 수정을 거쳐본 뒤에 올려보려고 한다.

이전까지의 회고는 주차마다 프론트-백 순서로 매번 다른 회고를 했었는데, 이번에는 WEEK5와 6 모두 백엔드를 개발했다. WEEK5에는 프론트 이후의 백, WEEK6는 백을 먼저 개발하고 프론트를 개발하게 되는 프로젝트였다. 기능은 조금 다르지만, 비슷한 기술을 사용해서 이번에는 WEEK5에서 WEEK6, 두번의 백엔드 미션을 하면서 어떤 변화가 생겼는지 회고해보려고 한다.

WEEK5 > WEEK6로의 변화

WEEK5에는 앞서 공개한 페이지의 백엔드를 만들어보는 미션이었다. 첫번째 프로젝트가 로그인-회원가입 페이지를 만들어보는 거였는데, 두번째 프로젝트에서도 로그인이 필요해서 첫번째 프로젝트에서 더 잘 짰으면 잘 마무리할 수 있었을텐데 하는 아쉬움이 남았다.

그래도 이번엔 로그인 모듈의 활용이 가능해서 좀 더 쉬운 방법(하지만 이해하는 것까지 쉽다곤 안했다)으로 로그인을 구현할 수는 있었고, 모듈에 대한 사용법을 익히면서 세션 로그인에 대해 다시한번 정리해보는 좋은 시간을 가질 수 있었다.

웹에서는 로그인-회원가입이 빠질 수 없기 때문에 세번째 프로젝트에서도 어김없이 구현을 하게 됐는데, 역시 여러번 반복을 하다보니 조금 더 익숙해질 수 있어서 express와 passport 모두 더 좋은 코드 방식으로 개선하면서 기능을 구현할 수 있었다.

서버에 배포하기

이전 프로젝트에서는 배포를 heroku에 맡겼지만, 이번 두 프로젝트는 NBP의 nCloud를 활용해 배포하게 되었다. 처음 시도해보는 배포라 어려운 점이 많았는데, 특히 최초에는 외부에서의 접근을 모두 차단하도록 되어있어서 서버와 통신하기까지 엄청난 시간이 들었다. 마스터님과 함께 간략하게 서버를 설정하는 방법을 배우긴했지만 제대로 이해하질 못해서, 서버를 열고 MySQL DB를 설치해서 코드로 DB 서버와 통신하기까지 무려 이틀이나 걸렸다. 바보같이 비공인 IP에 계속 접속을 시도했기 때문이었다. 외부 접속일 땐 등록된 공인 IP로 해야한다!

그래도 이런 갖은 삽질 덕분에 WEEK6 프로젝트에서는 새로운 서버를 열고, MySQL 서버와 통신하는데까지 그다지 오랜 시간이 걸리지 않았다.

공인 IP에서 포트에 대한 전체 IP 여는건 위험해!

WEEK5에는 내 PC의 IP는 위치에 따라 유동적이다보니, 방화벽 설정에서 모든 IP에 대해서 DB 접근을 허용하도록 했었다. 그런데 부캠러 중에 포트 스캔 공격을 당했는지, Bit Coin 메일을 받게 된 분이 있었다.. 작은 서버였고 데이터는 모두 Git에도 저장되어있으니 서버를 새로 열면 되는 일이었지만, 서비스되는 서버였다면 큰일날 일이다. 나도 이렇게 되면 어떡하지..! 했지만 NBP에서의 교육을 통해서 좀 더 안전한 방법을 배울 수 있었다.

SSL VPN이라는 것을 활용하면 좀 더 안전한 접근이 가능하게 되는데, 유저를 서버에 등록하고 SSL VPN 클라이언트를 다운로드 받아 계정을 입력, 로그인하면 비공인IP 주소로 접속하여 이용할 수 있다. 계정을 소유하고 있는 사람만 접속이 가능하기 때문에 이 계정이 유출되지 않는 이상 비공인IP로 접속할 수 있는 사람은 나 뿐이라서 더 안전하다고 할 수 있다 :D

데이터베이스, SQL 설계하기

데이터베이스 매니저 모델링

WEEK5에는 데이터를 저장할 DB를 간단하게 설계한 뒤에 모든 테이블이 공통적으로 사용할 수 있게 CRUD API를 만들어봤다. 그 결과로 select, update, insert, delete 함수들을 만들어서 사용했었는데 지정된 쿼리 형태에 조건들을 끼워맞춰야해서 편한 형태는 아니었다. 게다가 select(column, condition) 형태로 쿼리를 사용했다면 어떤 조건의 무엇을 select 한 것인지 다시 한번 더 봐야해서 가독성이 좋은 형태로 작성되진 못했던 것 같다.

그래서 WEEK6에는 조금 달리 구현을 해봤다. 연결을 맺고 query를 날려주는 함수를 기본적으로 가지고 있는 DBManager 클래스를 하나 작성하고, 이를 상속해서 user table을 관리하는 userDBManager 등 테이블 별로 DB 모델을 따로 둬서 해당 DBManager에는 관련 쿼리만 작성되도록 나눠 구현해보았다. 이번에는 모델별로 쿼리가 나뉘어있기 때문에 좀 더 관리하기 쉬웠고, 함수 형태로 관리해서 쿼리를 사용하는 구간을 일일히 찾아다닐 필요가 없어 좋았다.

개인적으로 쿼리를 관리하는데는 WEEK6 때 사용했던 방식이 더 좋은 방식인 것 같다. DB가 변경되어서 쿼리를 변경한다고 해도 유저를 가져온다(findUserById)는 함수명 자체는 변경될 필요가 없기 때문에, DB 모델의 쿼리만 변경하면 Router에서는 수정할 필요가 전혀 없기 때문이었다. 실제로 DB의 스키마가 여러번 변경되었는데, 모델 쿼리만 변경해도 대부분 잘 동작하는 것을 확인할 수 있었다.

데이터베이스 설계

WEEK5에서는 테이블 간의 연관이 별로 없어서 설계가 그렇게 어려운 점이 없었다. 단지 테이블에 어떤 컬럼을 두는게 좋을까? 라는 생각을 가졌던 것이 전부였고, 단순했기 때문에 DB 스키마가 변경된 적도 없었던 것 같다.

WEEK6에서의 데이터베이스는 연결 고리가 굉장히 많았다. TODO 보드를 만드는데, 유저-보드-보드 권한-카드리스트-보드 로그 등 저장해야 될 정보가 매우 많았고, 유저가 삭제되면 보드도 함께 사라져야하는 등의 생각해야할 조건들이 많았다.

최대한 어렵지 않게 설계하기 위해서 추가 기능 개선을 할 때의 조건들은 빼고 데이터 베이스를 설계했는데도 여러번 각 컬럼 조건 값들이 변경되기도 하고, 어떤 컬럼은 아예 사라지기도, 외래키를 넣었다 뺏다 반복하기도 했다. 이 과정들을 반복하면서 왜 DBA가 따로 직업으로 까지 존재하는지 이해할 수 있었다. 유저가 많지 않은 DB임에도 불구하고 간단한 쿼리, 성능을 위해 한참을 설계하는데 하물며 몇백만이 넘는 유저가 있는 서비스의 DB의 설계는 얼마나 오래 걸리겠는가… 데이터베이스를 잘하는 사람들이 존경스러웠던 시간이었다.

민감한 정보 감추기

데이터 베이스의 주소, 계정 정보와 같은 것들은 절대 외부로 노출되서는 안될 민감한 정보이다. WEEK5의 미션을 하면서 실수로 계정 정보가 올라가버렸는데, private 저장소여서 다행이지 public이었다면 아마 큰일.. 이런 불상사를 막기 위해 dotenv라는 환경변수 설정 모듈이 있다. WEEK5에서는 이런 모듈이 있다는 것을 몰라서 json 객체 형태로 값을 저장해두고 가져오는 식으로 사용했는데, WEEK6에서는 이제 알게되었으니 제대로 사용해보았다.

.env파일을 만들고 여기에 민감한 정보들을 환경변수로 담고, 코드에서는 해당 환경변수를 호출하면 된다. 이 때 .env파일은 절대 외부로 노출해선 안되고, 만약 오픈소스처럼 다른 이들에게 공유하고 싶다면 .dev.env와 같은 파일을 제공해 어떤 환경변수들이 있는지 이름을 제공하고 값은 사용자가 알아서 채워넣도록 하면 된다.

이렇게 사용하면 민감한 정보들을 감출 수 있기도 하지만 .env파일만 변경하면 한번에 DB주소도, 계정 정보도 바꿀 수 있다는 점! 세상엔 좋은 모듈이 정말 많다.


WEEK5와 6의 미션을 요약하자면 DB 였던 것 같다. 아무래도 서버에서는 대부분 DB를 통해 얻은 데이터를 프론트로 전송하다보니 그렇겠지!

새로운 개념들이 많아서 미션을 완성하기 촉박했기 때문에 체력적인 소모가 많았던 주였다. 거기다 WEEK6에는 쉬는 날이 중간에 껴있어서 그랬는지, 6주간 쉼없이 달려왔기 때문인지 힘이 잘 생기지 않아서 팀원들과 힘든 나날들을 보냈다. 리프레시하고 WEEK7에는 또 제대로 된 미션을 완수해야하는데 이번주에도 쉬는날이 있어서 조금 두렵지만 쉬는 날을 기회 삼아 더 좋은 프로젝트를 완성할 수 있게 되기를!

내일의 프로젝트를 위해 지난 2주간의 회고는 이만 줄여야 할 것 같다. 다음주 회고는 꼭 미루지 말자!!