이번 프로젝트 핵심은 손님이 세탁물을 신청하면 사장님이 손님의 세탁물 목록을 실시간으로 조회할 수 있고, 사장님이 세탁물 상태를 변경할 때마다 손님과 사장님의 재화(포인트)가 움직이는 것이었다.
실시간 업데이트를 하려면 서버에서도 클라이언트 측에 요청을 보낼 수 있어야 하고, 그러려면 socket
을 사용해야 한다.
강의에서 socket.io에 대해 간단하게 배우기는 했으나 프로젝트에 적용시키기에는 무리가 있어서 api
로만 진행을 했다. (새로고침으로 데이터를 불러오는 방식)
초기에 DB 관계도를 설정할 때부터 고민이 되었던 것은 손님과 사장님의 테이블을 하나로 할 것인지, 분리할 것인지였다.
테이블을 하나로 한다면 손님과 사장님을 구분하는 컬럼을 추가하는 방법이 있었는데, 고민 끝에 우선 테이블을 user와 boss로 분리하게 되었다.
결과적으로는 테이블을 하나로 하는 것이 리소스를 줄일 수 있는 선택이었던 것 같다.
user와 boss 테이블을 나누게 되면서 회원가입, 로그인 페이지, middleware 등 api를 모두 2가지 갈래로 나눠야 했다.
다음 번에 비슷한 유형의 프로젝트를 한다면 하나로만 해서 진행할 수 있는 방법을 시도해봐야겠다.
작성한 ERD에 근거하여 관계 설정이 필요했다. 이번 프로젝트에서는 sql raw query가 아닌 sequelize를 사용했기 때문에 models 폴더에서 static associate(models)
로 관계 설정을 했다.
hasMany
와 BelongsTo
로 외래키를 설정할 수 있다.
static associate(models) {
models.Boss.hasMany(models.Laundry, {foreignKey: "boss_id", sourceKey: "id",});
models.Boss.hasMany(models.Review, {foreignKey: "boss_id", sourceKey: "id",});
models.Laundry.belongsTo(models.Boss, {
foreignKey: "boss_id",
targetKey: "id",
});
예를 들어 Boss 모델은 Laundry 모델의 컬럼을 여러 개 가질 수 있고, id 값을 Laundry의 boss_id로 참조하게 된다. (한 명의 사장은 여러 개의 세탁물을 가질 수 있음)
Review 모델도 마찬가지로 설정했다.
sequelize의 편리하면서도 불편한(?) 점은 DB를 변경할 때 models 파일만 변경하면 되는 게 아니라 migration을 해줘야 한다는 점이다.
migration 파일이 생성되면 이전 버전으로 롤백할 수 있다는 장점도 있지만 반대로 작은 수정 사항도 매번 migration을 해야 해서 살짝 귀찮다는 단점이 있다.
그래서 서버를 재실행할 때마다 migration을 자동으로 동기화해주는 sequelize.sync()
함수를 사용했다.
sequelize
.sync({ force: false })
.then(() => {
console.log("데이터베이스 연결 성공");
})
.catch((err) => {
console.error(err);
});
force
값을 true
로 하면 서버를 재실행할 때마다 DB가 완전히 초기화되어 기존 데이터가 모두 날아가니 조심해야 한다.
한번 DB 설정을 한 후에는 false
로 설정해주면 변경이 일어나지 않는다.
alter: true
를 하면 데이터 삭제 없이 변경사항이 적용된다.
다만 변경 시 데이터 타입이 기존 데이터와 일치하지 않으면 에러가 발생한다.
다음 포스팅에서는 손님과 사장님의 회원가입과 로그인을 구현하는 방법에 대해 정리할 예정이다.