Sequelize 시리즈
- [Node.js] Sequelize(1) - sequelize와 sequelize-cli
- [Node.js] sequelize(2) - 모델 정의하기
- [Node.js] sequelize(3) - CRUD + RESTful 게시판 만들기
- [Node.js] sequelize(4) - 관계 설정( association ) 및 게시판 댓글 구현하기
- [Node.js] sequelize(5) - seed 활용하기
- [Node.js] sequelize(6) - 제약조건 추가 ( custom validate )
- [Node.js] sequelize(7) - 검색기능에 필요한 query operator
- [Node.js] sequelize(8) - pagination
2019. 08. 11 수정
sequelize에서 모델을 정의할 때 컬럼의 옵션으로 validate를 작성할 수 있습니다.
validate는 단어 그대로 데이터가 타당한지, 유효한지를 확인하는 작업입니다.
sequelize 공식문서(링크)를 보시면 validation을 어떻게 작성하는지 예시가 나와있습니다.
참고로 sequelize validate는 validator.js 라는 모듈을 사용합니다. ( 링크 )
sequelize에서 제공하는 validate외 에도, isEven()처럼 사용자가 직접 validate를 작성할 수 있습니다.
사실 이 부분이 가장 필요로 할 것 같으므로 custom validate에 대한 예시를 살펴보도록 하겠습니다.
1. 모델 정의할 때, Custom Validate 옵션 추가하기
이번 예제에서 구현하고자 하는 것은 회원가입을 할 때, 이메일 주소로 gmail만 받으려고 합니다.
고려해야 할 사항은 다음과 같습니다.
- 도메인 주소는 오직 "@gmail.com"만 허용
- @GMAIL.COM 으로 입력한 경우 소문자 처리
- 이메일 아이디는 영문 대소문자와 숫자만 가능
위 조건들을 충족하는 validate를 만들기 위해서는 정규식과 String객체의 match(), slice() 메서드를 사용합니다.
먼저, sequelize-cli를 통해 스켈레톤을 구성한 후, 다음과 같이 모델을 작성합니다.
/models/std.js
'use strict';
function isValidId(emailId){
for(let i = 0; i < emailId.length; i++){
let result = emailId[i].match(/\w/g)
if(result === null){
return false;
}
}
return true;
}
function isValidDomain(domain){
let googleDomain = "@gmail.com";
if(googleDomain === domain){
return true;
}
else{
return false;
}
}
module.exports = (sequelize, DataTypes) => {
var std = sequelize.define('std', {
stdEmail: {
type: DataTypes.STRING,
primaryKey: true,
validate:{
isGmail(inputEmail){
let inputEmailId = inputEmail.slice(0,-10);
let inputEmailDomain = inputEmail.slice(-10).toLowerCase();
if( !isValidId(inputEmailId) || !isValidDomain(inputEmailDomain)){
throw new Error("이메일 형식이 맞지 않습니다.")
}
}
}
},
stdName: {
type: DataTypes.STRING,
allowNull: false,
},
stdPwd: {
type: DataTypes.STRING,
allowNull: false,
},
salt: {
type: DataTypes.STRING
},
});
return std;
};
예제와 같이 stdEmail 컬럼을 정의할 때 validate 옵션을 추가하면, 데이터가 추가될 때 validate가 실행됩니다.
즉, 이메일 양식이 맞는지 앞에서 언급한 3가지 사항을 체크하는 것이죠.
3가지 모두 만족하면, 타당한 이메일 주소이기 때문에 올바른 데이터로 간주하여, validate를 통과하게 됩니다.
2 custom validate 내용 살펴보기
sequelize에서 validate를 추가한 부분은 위에서 언급한 것이 전부입니다.
아래의 내용은 구글 도메인 주소만 받을 수 있도록 하는 validate를 구현한 부분을 살펴볼 것입니다.
1) validate
validate 프로퍼티의 값으로 custom validate 함수( isGmail )를 정의합니다.
그러면 사용자가 입력한 데이터는 인자로 전달되어 inputEmail 변수에 할당됩니다.
사용자가 입력한 이메일 주소는 다음과 같을 것입니다.
"somethingID@gmail.com"
이 문자열에 slice() 메서드를 사용하면, 이메일 아이디( somethidID )와 도메인 주소( @gmail.com )를 분리할 수 있을 것 같습니다.
- 전체 문자열에서 뒤에서 10글자는 inputEmail.slice( -10 ) 메서드의 반환값과 같으며, @gmail.com 문자열이 반환됩니다.
- 또한 소문자만 입력 받을수 있도록 했으므로, toLowerCase() 메서드를 호출하여 소문자로 변환합니다.
- 마찬가지로 이메일 아이디는 inputEmail.slice(0,-10) 메서드의 반환 값입니다.
다음으로 isValidDomain() , isValidId() 함수를 호출할 때,
이메일 아이디와 도메인 주소 두 값을 각각 인자로 전달하여 이메일 양식이 유효한지 체크합니다.
유효성 검사가 실패하면 Error 객체를 생성하는데, 이는 콘솔창에 출력되는 에러 메시지입니다.
2) isValidId 함수
isValidId() 함수가 호출될 때, 사용자가 입력한 이메일 아이디가 전달됩니다.
이메일 아이디를 반복문으로 돌면서, 영문자와 숫자만으로 구성이 되었는지 유효성 검사를 수행합니다.
여기서 match() 메서드와 정규식을 사용했습니다.
( match 함수는 여기를 정규식은 여기를 참고해주세요.
참고로 match 메서드 보다 search 메서드가 성능이 더 좋다고 하는데요, 선택은 자유입니다. - 참고 )
JS의 RegExp 객체는 자주 쓰이는 정규식을 미리 정의하여 지원을 해주고 있습니다.
예제에서는 문자열과 숫자만 포함하는 정규식이 필요하므로, 이를 찾아보면 \w가 있네요.
따라서 이메일 아이디가 영문자와 숫자로만 구성되어 있는지 확인하려면, 아래와 같이 작성할 수 있을 것 같습니다/
str.match( /\w/g )
3) isValidDomain 함수
이 함수는 매우 간단합니다.
매개변수로 받은 문자열이 "@gmail.com"이 맞는지 확인합니다.
validate에서 사용자가 입력한 이메일의 도메인을 소문자로 처리 했기 때문에 대문자는 고려하지 않아도 됩니다.
이상으로 sequelize에서 모델을 정의할 때 validate를 적용하는 방법에 대해 알아보았습니다.