본문 바로가기

nodejs

[Node.js] express-ajv Json 스키마 유효성 검증

회원가입 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}`)
})

 

결과

성공 

실패 


 

 

 

참고 : https://github.com/ajv-validator/ajv