sg-openapi-validator
Version:
openapi3.0 schema��� 이용해서 express로 들어오는 req의 값들을 validation 한다.
138 lines (120 loc) • 3.78 kB
JavaScript
const utils = require('./utils')
class OpenapiValidator {
/**
* error code를 리턴한다.
* @return {Object}
*/
getCodes() {
return utils.codes
}
/**
* 미들웨어 연결. req.validateParameters로 함수 validation 가능.
* @param {string} [prefix] - spec의 url의 추가적인 prefix가 있을 경우 입력한다.
* @returns {Function}
*/
validator(prefix) {
return (req, res, next) => {
const getUrl = (url) => {
if (prefix.indexOf('/') !== 0) {
prefix = '/' + prefix
}
if (prefix.indexOf('/') !== (prefix.length - 1) && url.indexOf('/') !== 0) {
prefix = prefix + '/'
}
url = prefix + url
url = utils.replaceExpressKeywordToOpenAPIKeyword(url)
url = utils.replaceRealKeywordToOpenAPIKeyword(url, req.spec.paths)
return url
}
/**
* openapi url 형태를 express url형태로 변경해준다.
* @param url
* @returns {*|string}
*/
req.convertOpenAPIUrlToExpressUrl = (url) => {
return getUrl(url)
}
/**
* Open API 3.0의 spec을 통해 현재 req에 요청된 parameter를 체크하여 validation 한다.
* @param {string} url - spec상의 현재 url
* @param {string} method - method
* @returns {*|Object[]}
*/
req.validateParameters = (url, method) => {
method = method.toLowerCase()
url = getUrl(url)
let schemaWrapper = req.spec.paths[url][method].parameters
const commonParameters = req.spec.paths[url].parameters
if (Array.isArray(commonParameters)) {
schemaWrapper = schemaWrapper.concat(commonParameters)
}
let errors = []
for (let i = 0; i < schemaWrapper.length; ++i) {
let wrapper = schemaWrapper[i]
let name = wrapper.name
let schema = wrapper.schema
let isRequired = !!wrapper.required
let inputName = null
if (wrapper.in === 'header') {
inputName = 'headers'
} else if (wrapper.in === 'query') {
inputName = 'query'
} else if (wrapper.in === 'path') {
inputName = 'params'
} else if (wrapper.in === 'cookie') {
inputName = 'cookie'
}
let instance = req[inputName][name]
if (instance === undefined && isRequired === true) {
errors.push({
code: 'invalidRequired',
msg: 'invalidRequired',
domain: inputName,
param: name,
value: instance
})
} else {
errors = [...errors, ...utils.getErrors(instance, schema, inputName, name)]
}
}
return errors
}
/**
* Open API 3.0의 spec을 통해 현재 req에 요청된 requestBody를 체크하여 validation 한다.
* @param url
* @param method
* @returns {*|Object[]}
*/
req.validateRequestBody = (url, method) => {
method = method.toLowerCase()
url = getUrl(url)
let schema = req.spec.paths[url][method].requestBody
if (schema && schema.content['application/json'] && schema.content['application/json'].schema) {
let instance = req.body
let realSchema = schema.content['application/json'].schema
return utils.getErrors(instance, realSchema, 'body', 'requestBody')
} else {
return []
}
}
/**
* swagger schema의 parameters 객체 스펙과 express의 req 객체를 받아서 spec에 정의된 데이터타입으로 query, params의 값들을 변경한다. (params, query에는 모두 string만 들어있다.)
* @type {module.exports.convertParameterType}
*/
req.convertParameterType = utils.convertParameterType
next()
}
}
/**
* Open API 3.0 전체 spec을 req에 연결
* @param {Object} specObj - Open API Full spec.
* @returns {Function}
*/
bindSpec(specObj) {
return (req, res, next) => {
req.spec = specObj
next()
}
}
}
module.exports = new OpenapiValidator()