0. 기존코드
// regex.ts
export const registerRegexesOfType = {
email: {
regexes: [/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}$/],
msg: '이메일의 형식에 맞게 입력해주세요.',
},
password: {
regexes: [/^(((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]))|((?=.*\d)(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z]))).{6,15}$/],
msg: '비밀번호는 6자 이상 15자 이하의 영문+숫자이어야 합니다.',
},
phone: {
regexes: [/^01\d\d{3,4}\d{4}$/],
msg: '핸드폰 번호의 양식에 맞게 입력해주세요.',
},
};
// auth/service.ts
import { registerRegexesOfType } from '~/libs/util/regex';
import ErrorResponse from '~/libs/exception/errorResponse';
export const userSignUpController = async (req: ISignUpController, res: Response, next: NextFunction) => {
const { email, password, phone } = req.body;
if (!email && !password && !phone) {
return next(new ErrorResponse(ERROR_CODE.INVALID_INPUT_VALUE));
}
if (email) {
const emailRegexes = registerRegexesOfType.email.regexes;
const isEmailValid = emailRegexes.some((regex) => regex.test(email));
if (!isEmailValid) {
return next(new ErrorResponse(ERROR_CODE.EMAIL_INVAILD_INPUT));
}
}
if (password) {
const passwordRegexes = registerRegexesOfType.password.regexes;
const isPasswordValid = passwordRegexes.some((regex) => regex.test(password));
if (!isPasswordValid) {
return next(new ErrorResponse(ERROR_CODE.PASSWORD_INVAILD_INPUT));
}
}
if (phone) {
const phoneRegexes = registerRegexesOfType.phone.regexes;
const isPhoneValid = phoneRegexes.some((regex) => regex.test(phone));
if (!isPhoneValid) {
return next(new ErrorResponse(ERROR_CODE.PHONE_INVAILD_INPUT));
}
}
try {
await userSignUpService({ email, password, phone});
return res
.status(httpStatus.CREATED)
.json({ status: httpStatus.CREATED, message: '정상적으로 회원가입 되었습니다.' });
} catch (e) {
return next(e.message);
}
};
코드를 보니 유효성검사하는 로직이 반복되어서 함수로 추출할 수 있을것 같다.
1. 유효성검사 객체 수정
// regex.ts
export const registerRegexesOfType = {
email: {
regexes: [/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}$/],
},
password: {
regexes: [/^(((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]))|((?=.*\d)(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z]))).{6,15}$/],
},
phone: {
regexes: [/^01\d\d{3,4}\d{4}$/],
},
};
우선 msg 키값은 errorCode라는 파일에 모듈화가 되어있어 중복내용이라 제거했다.
그랬더니 key값을 하나 더 줄일 수 있었다.
// regex.ts
export const registerRegexesOfType = {
email: [/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}$/],
password:[/^(((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]))|((?=.*\d)(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z]))).{6,15}$/],
phone: [/^01\d\d{3,4}\d{4}$/]
};
위처럼 regex 관리하는 객체가 깔끔해졌다.
2. 유효성검사 코드 모듈화
// validate.ts 파일을 만들어서 모듈화
//AS-IS
import { registerRegexesOfType } from '~/libs/util/regex';
export const validateInput = (input, type) => {
const regexes = registerRegexesOfType[type]?.regexes || [];
const isValid = regexes.some((regex) => regex.test(input));
return isValid;
};
//TO-BE
import { registerRegexesOfType } from '~/libs/util/regex';
export const validateInput = (input) => {
const isValid = registerRegexesOfType.some((regex) => regex.test(input));
return isValid;
};
우선 validate.ts 파일을 만들어서 모듈화시켰다.
이제 type을 넣어줄 필요가 없다. input값만 넣어주면 된다.
3. 유효성 검사 로직 수정
//AS-IS
if (!validateInput(email)) {
return next(new ErrorResponse(ERROR_CODE.EMAIL_INVAILD_INPUT));
}
if (!validateInput(password)) {
return next(new ErrorResponse(ERROR_CODE.PASSWORD_INVAILD_INPUT));
}
if (!validateInput(phone)) {
return next(new ErrorResponse(ERROR_CODE.PHONE_INVAILD_INPUT));
}
위처럼 수정이 되었다.
근데, 위 코드도 중복이 보인다.
모듈화를 시켜서 짧게 만들어주자.
// validate.ts 파일에 추가해서 모듈화
export const validateErrorResponse = (input, errorMessage, next) => {
if (!validateInput(input)) {
throw new ErrorResponse(errorMessage);
}
};
// TO-BE
validateErrorResponse(email, ERROR_CODE.EMAIL_INVAILD_INPUT);
validateErrorResponse(password, ERROR_CODE.PASSWORD_INVAILD_INPUT);
validateErrorResponse(phone, ERROR_CODE.PHONE_INVAILD_INPUT);
validateErrorResponse를 유틸함수로 떼어내서 사용하므로 미들웨어로 사용할 수 없어
next -> throw로 수정하였다.
4. 최종
export const registerRegexesOfType = {
email: [/^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}$/],
password:[/^(((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]))|((?=.*\d)(?=.*[a-z]))|((?=.*\d)(?=.*[A-Z]))).{6,15}$/],
phone: [/^01\d\d{3,4}\d{4}$/]
};
export const validateInput = (input) => {
const isValid = registerRegexesOfType.some((regex) => regex.test(input));
return isValid;
};
export const validateErrorResponse = (input, errorMessage, next) => {
if (!validateInput(input)) {
throw new ErrorResponse(errorMessage);
}
};
validateErrorResponse(email, ERROR_CODE.EMAIL_INVAILD_INPUT);
validateErrorResponse(password, ERROR_CODE.PASSWORD_INVAILD_INPUT);
validateErrorResponse(phone, ERROR_CODE.PHONE_INVAILD_INPUT);
코드가 중복되거나 공통부분이 보인다면
차근차근 중복요소를 모듈화해가면서 코드의 가독성을 쉽게 만들자.
미래의 내가 편해진다...!
참고
'JaveScript > ExpressJS' 카테고리의 다른 글
APM tool을 Expressjs에 연동하기 (0) | 2024.04.10 |
---|---|
async/await 를 Promise.allSetted로 리팩토링하기 (0) | 2024.03.31 |
if-else => switch-case 리팩토링 (0) | 2024.03.25 |
Redis로 Refresh Token 관리 (1) | 2024.01.15 |
ExpressJS와 ChatGPT 연동 (2) (1) | 2023.12.26 |