Wondering what’s next for npm?Check out our public roadmap! »

    koa-swagger-decorator
    TypeScript icon, indicating that this package has built-in type declarations

    1.7.4 • Public • Published

    koa-swagger-decorator

    using decorator to auto generate swagger json docs

    build status npm

    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
    • babel support for decorator (or using typescript)
    // 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

    // router.js
    import Router from 'koa-router'
    
    import Test from './test'
    
    import { SwaggerRouter } from 'koa-swagger-decorator'
    
    const router = new SwaggerRouter([KoaRouterOpts],[SwaggerOpts]) // extends from koa-router
    
    // swagger docs avaliable at http://localhost:3000/api/swagger-html
    router.swagger({
      title: 'Example Server',
      description: 'API DOC',
      version: '1.0.0',
    
      // [optional] default is root path.
      // if you are using koa-swagger-decorator within nested router, using this param to let swagger know your current router point
      prefix: '/api',
    
      // [optional] default is /swagger-html
      swaggerHtmlEndpoint: '/swagger-html',
    
      // [optional] default is /swagger-json
      swaggerJsonEndpoint: '/swagger-json',
    
      // [optional] additional options for building swagger doc
      // eg. add api_key as shown below
      swaggerOptions: {
        securityDefinitions: {
          api_key: {
            type: 'apiKey',
            in: 'header',
            name: 'api_key',
          },
        },
      },
      // [optional] additional configuration for config how to show swagger view
      swaggerConfiguration: {
        display: {
          defaultModelsExpandDepth: 4, // The default expansion depth for models (set to -1 completely hide the models).
          defaultModelExpandDepth: 3, // The default expansion depth for the model on the model-example section.
          docExpansion: 'list', // Controls the default expansion setting for the operations and tags. 
          defaultModelRendering: 'model' // Controls how the model is shown when the API is first rendered. 
        }
      }
    })
    // map all static methods at Test class for router
    // router.map(Test);
    
    // mapDir will scan the input dir, and automatically call router.map to all Router Class
    router.mapDir(_path.resolve(__dirname), {
      // default: true. To recursively scan the dir to make router. If false, will not scan subroutes dir
      // recursive: true,
      // default: true, if true, you can call ctx.validatedBody[Query|Params] to get validated data.
      // doValidation: true,
      // default: [], paths to ignore while looking for decorators 
      // ignore: ["**.spec.ts"],
    })

    using decorator to make api definition

    // test.js
    
    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' }, // item's type will also be validated
      },
    }
    
    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.request.body;
        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 // @request('POST', '/users')
    
    tags // @tags(['example'])
    query // @query({limit: {type: 'number', required: true, default: 10, description: 'desc'}})
    
    path // @path({limit: {type: 'number', required: true, default: 10, description: 'desc'}})
    
    body // @body({groups: {type: 'array', required: true, items: { type: 'string', example: 'group1' }}})
    
    formData // @formData({file: {type: 'file', required: true, description: 'file content'}})
    
    middlewares
    // support koa middlewares.
    // eg. @middlewares([func1,func2])
    
    security 
    // define authentication method, key must be same as one of methods defined in swaggerOptions.securityDefinitions
    // @security([{ api_key: [] }]) 
    
    summary // @summary('api summary')
    
    description // @description('api description')
    
    responses
    // @responses({ 200: { description: 'success'}, 400: { description: 'error'}})
    // responses is optional
    
    deprecated // @deprecated
    
    @orderAll(1)  // weight 1 means the router class will be ordered at position 1 in generated doc
    @tagsAll(['A', 'B'])
    @deprecatedAll
    @securityAll([{ api_key: [] }])
    @middlewaresAll([log1, log2]) // add middlewares [log1, log2] to all routers in this class
    @queryAll({ limit: { type: 'number', default: 444, required: true } }) // can be merged with @query
    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), {
      // default: true, if true, you can call ctx.validatedBody[Query|Params] to get validated data.
      doValidation: false,
    })
    runing the project and it will generate docs through swagger ui

    image.png

    generate swagger.json without starting the server
    import path from 'path';
    import { SwaggerRouter } from '../../dist';
    
    // init router
    const router = new SwaggerRouter();
    
    // load controllers
    router.mapDir(path.resolve(__dirname, '../routes'));
    
    // dump swagger json
    router.dumpSwaggerJson({
      filename: 'swagger.json', // default is swagger.json
      dir: process.cwd(), // default is process.cwd()
    });

    License

    © MIT

    Install

    npm i koa-swagger-decorator

    DownloadsWeekly Downloads

    1,525

    Version

    1.7.4

    License

    MIT

    Unpacked Size

    178 kB

    Total Files

    64

    Last publish

    Collaborators

    • avatar