회원가입 API를 호출했을 때 닉네임, 아이디, 패스워드가 필수로 클라이언트에서 보내줘야 한다 했을 때
단순하게 if,else를 사용하여 체크를 할 수 있긴 하지만 항목이 많아진다면 코드가 더러워지는 문제가 있다.
이때 스키마 유효성 검사인 ajv를 사용한다면 좀 더 깔끔하게 유효성 검사를 할 수가 있다.
설치
npm install ajv ajv-errors
소스코드
파일 : ajv.middleware.js
body, query, params, file 메서드를 각각 구현을 해줬고 전달받은 스키마와 요청 값을 비교하여 틀릴 시 error 메시지를 반환하도록 하였는데 웬만하면 예외처리를 하는 게 좋다.
//파일명 : ajv.middleware.js
const Ajv = require('ajv');
const ajv = new Ajv({ verbose: true ,allErrors: true});
const ajvErrors = require('ajv-errors');
ajvErrors(ajv /*, {singleError: true} */)
const parseAjvErrors = (errors,res) => {
const error_message = errors;
res.send(error_message);
//아래처럼 예외처리도 가능하다. (이 경우에는 매개변수 res를 빼도 된다.)
//throw new BadRequestException(error_message);
};
const validate = (schema,req,res) => {
const validate = ajv.compile(schema);
if(validate(req)) {
return true;
}else {
parseAjvErrors(validate.errors[0].message,res);
}
}
const validateBody = (schema) => {
return (req, res, next) => {
if(validate(schema,req.body,res))
return next();
};
};
const validateQuery = (schema) => {
return (req, res, next) => {
if(validate(schema,req.query,res))
return next();
};
};
const validateFile = (schema) => {
return (req, res, next) => {
if(validate(schema,req.file,res))
return next();
};
};
const validateParams = (schema) => {
return (req, res, next) => {
if(validate(schema,req.params,res))
return next();
};
};
exports.validateParams = validateParams;
exports.validateBody = validateBody;
exports.validateQuery = validateQuery;
exports.validateFile = validateFile;
파일 : hello.schemas.js
JSON 스키마를 정의한다. 아래는 name 필드는 필수 값이며, 타입은 string 최소 길이는 2로 설정을 하였다.
//파일명 : hello.schemas.js
const ajv = {
hello: {
type: 'object',
required: ['name'],
properties: {
name: {
type: "string",
minLength : 2,
},
},
errorMessage: {
required: {
name: '이름은 필수 입력값 입니다.',
},
properties : {
name: '이름이 비어있거나 2 보다 작습니다.',
}
},
},
};
exports.ajvHello = ajv.hello;
파일 : server.js
위 셋팅이 끝나면 유효성 검증이 필요한 API에 미들웨어를 장착하고 스키마를 아규먼트로 추가해주면 된다.
//파일명 : server.js
const express = require('express')
const {validateParams, validateBody} = require("../middlewares/ajv.middleware");
const {ajvHello} = require("../schemas/hello.schemas");
const port = 3000
const app = express()
app.use(express.json()) // for parsing application/json
app.use(express.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded
//validateBody
app.post('/',validateBody(ajvHello), (req, res, next) => {
res.json(`Hello World ${req.body.name}`);
})
//validateParams
app.get('/:name',validateParams(ajvHello), (req, res, next) => {
res.json(`Hello World ${req.params.name}`);
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
결과
성공
실패
'nodejs' 카테고리의 다른 글
sentry 주요 기능 설명 (0) | 2022.03.03 |
---|---|
Node.js 보안 모듈 (helmet, hpp) (0) | 2022.02.16 |
[Node.js] express i18n 다국어 사용방법 (0) | 2021.12.13 |
[Node.js] Sequelize Create 메서드에서 특정 레코드만 반환 (0) | 2021.11.10 |