mares-swagger-spec-maker
v1.0.19
Published
mares framework ���조에 맞춰서openapi spec을 combine 해주는 모듈입니다.
Downloads
9
Readme
mares-swagger-spec-maker
mares framework 구조에 맞춰서openapi spec을 combine 해주는 모듈입니다.
Installation
npm install --save mares-swagger-spec-maker
Example
const specMaker = require('mares-swagger-spec-maker')()
// setting project root spec,
let rootSpec = require('./.root-api-spec.js')
// 각 서비스의 폴더를 추가해준다. 배열로 추가가 가능하다. 서비스별 폴더 구조는 아래에서 다시 설명한다.
rootSpec = specMaker.merge(rootSpec, [require('./service-name')])
// api prefix가 있다면 추가해준다.
rootSpec.paths = specMaker.addPrefix(rootSpec.paths, this._prefix) //optional
root spec의 경우 .root-api-spec.js
라고 이름지어 줘야 하며, 형태는 다음과 같다. version
, servers
, info
, components
정의가 가능하다.
module.exports = {
openapi: "3.0.0",
servers: [{
url: env === 'development' ? 'http://localhost:8080' : 'https://aaaaa.com'
}],
info: {
description: packageJson.description,
version: packageJson.version,
title: packageJson.name,
termsOfService: 'http://swagger.io/terms/',
contact: {
email: '[email protected]'
},
license: {
name: 'Private',
url: 'http://aaaa.com'
}
},
components: {
schemas: {
Error: {
type: 'object',
required: ['rows', 'count'],
properties: {
rows: {
type: 'string',
},
count: {
type: 'integer',
description: '전체 에러의 수',
example: 1,
nullable: false
}
}
}
}
}
}
컨텍스트별 스펙의 경우 .context-api-spec.js
과 같이 파일명을 지어야 하며 형태는 아래와 같다. root components를 overriding 하고, tag를 지정하는데 사용된다.
const meta = GET_META('infra-message');
const spec = {
tags: [{
name: 'message',
description: '문자 발송, 발송된 문자 조회 등의 기능을 담은 API.'
}],
components: {
securitySchemes: {
ApiKeyAuth: {
type: 'apiKey',
in: 'header',
name: 'X-API-TOKEN'
}
},
schemas: {
PhoneNum: {
type: 'string',
pattern: /(^\+[0-9]{2}|^\+[0-9]{2}\(0\)|^\(\+[0-9]{2}\)\(0\)|^00[0-9]{2}|^0)([0-9]{9}$|[0-9\-\s]{10}$)/,
minLength: meta.std.message.minPhoneNumLength,
maxLength: meta.std.message.maxPhoneNumLength,
description: '문자를 받을 수 있는 전화번호, +국가코드 형태가 되어야 한다.',
example: '+821011112222',
nullable: false
}
},
parameters: {
messageContextLimitParam: {
in: 'query',
name: 'limit',
description: '최대 불러올 데이터 row 수',
required: false,
schema: {
type: 'integer'
},
example: meta.std.default.defaultContentsLength
}
}
}
}
module.exports = spec
다음으로 버전에 대한 스펙이 있다. .version-api-spec.js
라고 이름 지어줘야 한다.
module.exports = {
in: 'path',
name: 'version',
description: '버전 값',
required: false,
schema: {
type: 'string',
enum: ['v1'],
default: 'v1',
example: 'v1'
}
}
마지막으로 실제 router spec을 정의해야한다. .spec.js
로 정의한다. 전체 스펙에서 url 부분부터 정의를 해주면 된다.
const meta = GET_META('message-context');
const spec = {
'/{version}/messages': {
get: {
tags: ['message'],
summary: '문자 내역 확인',
operationId: 'findMessages',
description: '해당 스펙에서 message 라는 의미는 발송된 문자를 의미한다. 해당 API는 발송했던 문자 내역을 불러온다.',
parameters: [{
$ref: '#/components/parameters/messageContextOffsetParam'
}, {
$ref: '#/components/parameters/messageContextLimitParam'
}, {
in: 'query',
name: 'templateKey',
description: '문자 발송시 이용된 템플릿의 키 겁색 (prefix 검색 가능)',
required: false,
schema: {
type: 'string',
example: 'templateKey123',
nullable: false
}
}],
responses: {
'200': {
description: '불러오기 성공',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
rows: {
type: 'array',
items: {
$ref: '#/components/schemas/MessageDomain'
},
description: '문자 도메인 배열'
},
count: {
type: 'integer',
description: '해당 조건에 해당하는 전체 문자 도메인 카운트'
}
}
}
}
}
}
}
}
}
}
module.exports = spec
최종적으로는 아래와 같이 사용이 가능하다.
const getSpec = () => {
// 최상단 루트 스펙을 가져온다.
let rootSpec = require(path.resolve(rootPath, '.root-api-spec.js'))
// 루프를 돌면서 마레스 모듈을 읽어와서 루트스펙에 머지한다,.
for (let i = 0; i < contexts.length; ++i) {
let moduleName = path.basename(contexts[i])
rootSpec = specMaker.merge(rootSpec, path.resolve(rootPath, moduleName))
}
// 모든 url에 prefix를 붙여준다. 예를들면 account/users 라는 리소스가 있다면 prefix/account/users라고 변경이 된다.
rootSpec.paths = specMaker.addPrefix(rootSpec.paths, prefix)
// 모든 루트스펙에 선언된 컴포넌트 ($ref) 를 실제 객체로 바꿔준다. (이유는 실제 객체를 통해 router에서 parameter, requestBody 등을 validation하기 위함이다.)
rootSpec = specMaker.replaceAllComponents(rootSpec)
// 필요한 곳에 리턴한다.
return rootSpec
}
Structure
폴더 및 파일 구조는 다음과 같다.
- 루트 프로젝트:
.root-api-spec.js
가 위치한다. - service 폴더: 서비스폴더 루트에
.context-api-spec.js
가 존재한다.- presentation: 프레젠테이션 레이어
- v1: api 버전폴더: 해당폴더 안에
version-api-spec.js
가 존재한다.- resourceName: 해당폴더 안에
.spec.js
가 존재한다.
- resourceName: 해당폴더 안에
- v1: api 버전폴더: 해당폴더 안에
- application: 어플리케이션 레이어
- domain: 도메인 레이어
- infra: 인프라스트럭쳐 레이어
- test: test 코드
- presentation: 프레젠테이션 레이어