koa-swagger-decorator
using decorator to auto generate swagger json docs
Installation
npm install koa-swagger-decorator
Contributing Guide
Please refer to contribution.md before creating your PR or issue.
Introduction
Koa Swagger Decorator
using decorator to auto generate swagger json docs add support validation for swagger definitions
based on Swagger OpenAPI Specification 2.0
support both javascript (babel required) and typescript
Example
// using commonds below to start and test the example server
git clone https://github.com/Cody2333/koa-swagger-decorator.git
cd koa-swagger-decorator
npm install
npm run start
finally open:
http://localhost:3000/api/swagger-html
Requirements
- Koa2
- @koa/router
- typescript (or babel required)
// add [transform-decorators-legacy] to .babelrc if using js
npm install --save-dev babel-plugin-transform-decorators-legacy
{
"presets": [
["env", {"targets": {"node": "current"}}]
],
"plugins": ["transform-decorators-legacy"]
}
Detail
for more detail please take a look at the example koa server
first wrapper the @koa/router object
import Router from '@koa/router'
import Test from './test'
import { SwaggerRouter } from 'koa-swagger-decorator'
const router = new SwaggerRouter([KoaRouterOpts],[SwaggerOpts])
router.swagger({
title: 'Example Server',
description: 'API DOC',
version: '1.0.0',
prefix: '/api',
swaggerHtmlEndpoint: '/swagger-html',
swaggerJsonEndpoint: '/swagger-json',
swaggerOptions: {
securityDefinitions: {
api_key: {
type: 'apiKey',
in: 'header',
name: 'api_key',
},
},
},
swaggerConfiguration: {
display: {
defaultModelsExpandDepth: 4,
defaultModelExpandDepth: 3,
docExpansion: 'list',
defaultModelRendering: 'model'
}
}
})
router.mapDir(_path.resolve(__dirname), {
})
using decorator to make api definition
import User from 'models/user'
import { request, summary, query, path, body, tags } from 'koa-swagger-decorator'
const testTag = tags(['test'])
const userSchema = {
name: { type: 'string', required: true },
gender: { type: 'string', required: false, example: 'male' },
groups: {
type: 'array',
required: true,
items: { type: 'string', example: 'group1' },
},
}
export default class Test {
@request('get', '/users')
@summary('get user list')
@security([{ api_key: [] }])
@testTag
@query({
type: { type: 'number', required: true, default: 1, description: 'type' },
})
static async getUsers(ctx) {
const users = await User.findAll()
ctx.body = { users }
}
@request('get', '/users/{id}')
@summary('get user info by id')
@security([{ api_key: [] }])
@testTag
@path({
id: { type: 'number', required: true, default: 1, description: 'id' },
})
static async getUser(ctx) {
const { id } = ctx.validatedParams
const user = await User.findById(id)
ctx.body = { user }
}
@request('post', '/users')
@testTag
@body(userSchema)
static async postUser(ctx) {
const body = ctx.validatedBody
ctx.body = { result: body }
}
static async temp(ctx) {
ctx.body = { result: 'success' }
}
}
using decorator to make api body
import Router from '@koa/router';
import { request, summary, query, path, body, tags, swaggerClass, swaggerProperty } from 'koa-swagger-decorator'
@swaggerClass()
export class subObject {
@swaggerProperty({ type: "string", required: true }) Email: string = "";
@swaggerProperty({ type: "string", required: true }) NickName: string = "";
@swaggerProperty({ type: "string", required: true }) Password: string = "";
};
@swaggerClass()
export class userInfo {
@swaggerProperty({ type: "string", required: true }) Email: string = "";
@swaggerProperty({ type: "string", required: true }) NickName: string = "";
@swaggerProperty({ type: "string", required: true }) Password: string = "";
@swaggerProperty({type:"object",properties:(subObject as any).swaggerDocument}) UserInfo:subObject;
};
export default class Test {
@request('POST', '/user/Register')
@summary('register user')
@description('example of api')
@body((userInfo as any).swaggerDocument)
static async Register(ctx: Router.IRouterContext) {
var params = (ctx as any).validatedBody as userInfo;
console.log(params);
}
}
avaliable annotations
- tags
- query
- path
- body
- formData
- middlewares
- security
- summary
- description
- responses
- deprecated
class annotations
- orderAll
- tagsAll
- responsesAll
- middlewaresAll
- securityAll
- deprecatedAll
- queryAll
request
tags
query
path
body
formData
middlewares
security
summary
description
responses
deprecated
@orderAll(1)
@tagsAll(['A', 'B'])
@deprecatedAll
@securityAll([{ api_key: [] }])
@middlewaresAll([log1, log2])
@queryAll({ limit: { type: 'number', default: 444, required: true } })
export default class SampleRouter {
...
}
validation
support validation type: string, number, boolean, object, array.
properties
in {type: 'object'}
and items
in {type: 'array'}
can alse be validated.
other types eg. integer
will not be validated, and will return the raw value.
by default, validation is activated and you can call ctx.validatedQuery[Body|Params] to access the validated value.
to turn off validation:
router.mapDir(_path.resolve(__dirname), {
doValidation: false,
})
runing the project and it will generate docs through swagger ui
generate swagger.json without starting the server
import path from 'path';
import { SwaggerRouter } from '../../dist';
const router = new SwaggerRouter();
router.mapDir(path.resolve(__dirname, '../routes'));
router.dumpSwaggerJson({
filename: 'swagger.json',
dir: process.cwd(),
});
License
© MIT