[sequelize] 모델 커스텀 메서드 선언 방법 (ES6)
예제 모델
// 기존의 sequelize Profile 모델
class Profile extends Sequelize.Model {
static init(sequelize, DataTypes) {
super.init({
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
name: {
type: DataTypes.STRING(200),
allowNull: false
},
email: {
type: DataTypes.STRING(200),
allowNull: false,
},
profile_url: {
type: DataTypes.TEXT,
allowNull: true,
}
});
return api_profile;
}
}
위와 같은 Profile 모델을 예시로 들겠습니다. 다른 스택오버플로우에 나와있는 방식은 전부 스택오버플로우 예시 같은 ES5
방식으로 함수 내에 선언되는 메서드로 많이 소개되어 있습니다.
module.exports = function(sequelize, DataTypes) {
return sequelize.define('Client', {
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
}, {
instanceMethods: {
getFullName: function() {
return this.first_name + ' ' + this.last_name;
}
}
});
};
하지만 제가 현재 사용하는 sequelize 모델은 ES6 기반 class
로 선언되어 있습니다. 위에 소개해드린 예시에서는 function 내에서 instanceMethods
라는 속성에 메서드를 하나씩 추가하는 구조입니다. 그래서 class
로 선언되어 있는 모델 또한 비슷하지 않을까? 라는 오해를 하기 쉬운 것 같습니다. 하지만 생각과 달리 정말 단순하게 사용할 수 있었습니다.
// 기존의 sequelize Profile 모델
class Profile extends Sequelize.Model {
static init(sequelize, DataTypes) {
super.init({
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
name: {
type: DataTypes.STRING(200),
allowNull: false
},
email: {
type: DataTypes.STRING(200),
allowNull: false,
},
profile_url: {
type: DataTypes.TEXT,
allowNull: true,
}
});
return api_profile;
}
static getEmailById = async (id) => {
const result = await this.findOne({
where: { id },
raw: true
});
return result;
}
}
위와 같이 클래스에 메소드를 선언하듯이 똑같이 선언하면 되겠습니다. 저는 static 메소드로 선언하였는데요. 아래에서 정적메서드를 어떻게 활용하는지, 커스텀 메서드 사용으로 router 처리 방식이 어떻게 바뀌는지 그리고 코드 중복을 방지할 수 있는 예제를 작성하겠습니다.
router.get('users/email/:id', async (req, res) => {
try {
const id = req.params.id;
// 쿼리가 더 복잡해진다면 비지니스 로직이 더 길어지게 됩니다.
const result = await DB.Profile.findOne({
where: { id },
raw: true
});
return res.json(result);
} catch (error) {
res.status(500).send(error.message);
next();
}
});
아래는 커스텀 메소드로 짧아진 로직입니다.
router.get('users/email/:id', async (req, res) => {
try {
const id = req.params.id;
const result = await DB.Profile.getEmailById(id);
return res.json(result);
} catch (error) {
res.status(500).send(error.message);
next();
}
});
이런 간단한 예제로 본다면 큰 차이가 없어 보입니다. 만약 사용자의 Profile
을 가져오는 값들이 테이블 3개를 Join
해서 가져와야 하는 값이라면 이야기가 달라집니다. 단순 쿼리 로직만 20~30줄이 될 수 있습니다. 그리고 사용자의 정보를 가져오는 쿼리는 다른 API에서도 많이 사용하는 데이터이기 때문에 custom
한 메서드로 분리하는 게 좋습니다.
'Node.js > sequelize' 카테고리의 다른 글
[sequelize] timestamp 에 날짜, 시간에 대한 타임존(timezone) 처리 방법 (0) | 2021.07.15 |
---|