GithubHelp home page GithubHelp logo

jayjaydee / routing-controllers-openapi-extended Goto Github PK

View Code? Open in Web Editor NEW

This project forked from dhineshpandiyan/routing-controllers-openapi-extended

0.0 1.0 0.0 577 KB

Runtime OpenAPI v3 schema generation for routing-controllers.

License: MIT License

TypeScript 99.23% JavaScript 0.77%

routing-controllers-openapi-extended's Introduction

routing-controllers-openapi-extended

Build Status

Swagger v2 and OpenAPI v3 schema generation using beautiful typescript decorators.

Table of Contents

About

This node module will extract much information about operations, parameters, responses from routing-controller decorator methods. Additinally it provides some more typescript decorators which will be useful to add user defined custom properties to the generated swagger specification. This library uses class-validator decorator to generate schema definitions currently.

Installation

npm i routing-controllers-openapi-extended

Usage

// UserController.ts

import { Body, Get, JsonController, Param, Post } from 'routing-controllers'
import { OperationInfo, ResponseEntry, Parameters, Model, Property } from 'routing-controllers-openapi-extended';

@Model()
export class CreateUserBody {
  
  @Property({ description: 'Name of the user'})
  name: string

  @Property({ itemType: String, description: 'List of user hobbies' })
  hobbies: string[]

}

@JsonController('/users')
export class UsersController {

  @Get('/:id')
  @OperationInfo({ summary: 'Get user by Id', description: 'Get user by Id' })
  @ResponseEntry({ statusCode: 200, schema: CreateUserBody, description: 'Retrived user by the supplied user id', examples: { 'applications/json': { userId: '<sample data>' } } })
  getOne(@Param('id') id: number) {
    return { name: 'User #' + id }
  }

  
  @Post('/:id')
  @Parameters([
    { name: 'Authorization', in: 'header', type: 'string', description: 'Used to attached token', required: true, default: 'Basic <token>' },
    { name: 'body', description: 'Detailed information about creat user body', required: true },
    { name: 'id', description: 'Detailed information about id parameter' },
  ])
  @ResponseEntry({ statusCode: 200, schema: CreateUserBody, description: 'Information about created user', examples: { 'applications/json': { userId: '<sample data>' } } })
  createUser(@Body() body: CreateUserBody, @Param('id') id: string) {
    return { ...body, id: 3 }
  }

}


// SchemaGenerator.ts:

import 'reflect-metadata'
import { getMetadataArgsStorage } from 'routing-controllers'
import { generateSwagger } from 'routing-controllers-openapi-extended'

import { UsersController, CreateUserBody } from './UsersController'

const spec = generateSwagger({
  controllers: [UsersController],
  models: [CreateUserBody],
  storage: getMetadataArgsStorage(),
}, {
  info: {
    description: 'Generated by script',
    title: 'A sample API',
    version: '1.0.0'
  }
});

console.log(JSON.stringify(spec, undefined, 2));

This will generate below swagger v2 specification:

{
  "swagger": "2.0",
  "paths": {
    "/users/{id}": {
      "get": {
        "operationId": "UsersController.getOne",
        "summary": "Get user by Id",
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "Retrived user by the supplied user id",
            "examples": {
              "applications/json": {
                "userId": "<sample data>"
              }
            },
            "schema": {
              "$ref": "#/definitions/CreateUserBody"
            }
          }
        },
        "description": "Get user by Id"
      },
      "post": {
        "operationId": "UsersController.createUser",
        "summary": "Create user",
        "tags": [
          "Users"
        ],
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "type": "string",
            "description": "Detailed information about id parameter"
          },
          {
            "in": "body",
            "name": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/CreateUserBody"
            },
            "description": "Detailed information about creat user body"
          },
          {
            "name": "Authorization",
            "in": "header",
            "type": "string",
            "description": "Used to attached token",
            "required": true,
            "default": "Basic <token>"
          }
        ],
        "responses": {
          "200": {
            "description": "Information about created user",
            "examples": {
              "applications/json": {
                "userId": "<sample data>"
              }
            },
            "schema": {
              "$ref": "#/definitions/CreateUserBody"
            }
          }
        }
      }
    }
  },
  "definitions": {
    "CreateUserBody": {
      "type": "object",
      "required": [
        "name",
        "hobbies"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "Name of the user"
        },
        "hobbies": {
          "type": "array",
          "description": "List of user hobbies",
          "items": {
            "type": "string"
          }
        }
      }
    }
  },
  "info": {
    "description": "Generated by script",
    "title": "A sample API",
    "version": "1.0.0"
  }
}

Check /sample for a complete sample application.

Available API's

.generateSwagger({ controllers, models, storage }, additional)

This API will be used to generate swagger 2.0 specifications.

.generateOpenAPI({ controllers, models, storage }, additional)

This API will be used to generate Open API 3.0 configurations.

Available Decorators

@OperationInfo(options)

This is used to specify most of the basic information about each operations.

Available Options

  • summary [String] - used to specify summary information about operation
  • description [String] - used to specify description information about operation
  • operationId [String] - used to specify / override operation id about operation
  • consumes [Array<string>] - used to specify consumer list
  • produces [Array<string>] - used to specify produces list
  • security [any] - allow user to define their own security specification

Syntax

{
  summary?: string;
  description?: string;
  operationId?: string;
  consumes?: Array<string>;
  produces?: Array<string>;
  security?: any;
}

Example

@OperationInfo({ summary: '<summary info>', description: '<detailed info>', operationId: '<unique operation id>' })

@CustomEntry(options)

This is used to add all custom properties which may/ may not be specified in swagger sepcification.

Available Options

  • <any key name> [any] - entire object will be attached to the specific operation

Syntax

{
  [key: string]: any;
}

Example

@CustomEntry({ customField: '<values>', 'x-status': '<status>' })

@CodeSnippets(options)

This is another kind of custom entry which can be attached to operation sepcification.

Available Options

  • lang [String] - used to specify language
  • snippet [String] - used to specify sample code

Syntax

Array<{
  lang: string;
  snippet: string;
}>

Example

@CodeSnippets([{ lang: '<language>', snippet: '<code snippet>' }])

@Parameters(options)

This is used to add additional properties to the existing parameter (including query parameter and body parameters). And allow user to attach any header parameters (like pagination, content-type etc).

Available Options

  • name [String] - used to specify name
  • in [String] - used to specify type of parameter
  • description [String] - used to specify description
  • type [String] - used to data type of the parameter
  • required [Boolean] - used to required flag
  • schema [Object] - used to specify schema of the data type
  • examples [Object] - used to specify examples
  • example [any] - used to specify sample example
  • default [any] - used to specify default value
  • format [any] - used to specify format value (like int64)
  • <any key name> [any] - entire object will be attached to the specific operation

Syntax

{
  name: string;
  in?: 'query' | 'header' | 'path' | 'body' | 'cookie';
  description?: string;
  type?: string;
  required?: boolean;
  deprecated?: boolean;
  schema?: { $ref: string };
  examples?: {
      [key: string]: any;
  };
  example?: any;
  default?: any;
  format?: any;
  [key: string]: any;
};

Example

Users shall attach additinal parameters to the existing operation.

@Parameters({ name: 'Authorization', in: 'header', type: 'string', description: 'Used to attached token' required: true, default: 'Basic <token>'})

User shall use the same Parameters decorator to override/ amend existing paramters.

name value should match with the @Param name for query and path parameter entiries.

name value should be body for @Body type paramters.

@Post('/:id')
@Parameters([{ name: 'Authorization', in: 'header', type: 'string', description: 'Used to attached token' required: true, default: 'Basic <token>'}])
@Parameters([
  { name: 'body', description: 'Detailed information about creat user body', required: true }
])
@Parameters([
  { name: 'id', description: 'Detailed information about id parameter'}
])
createUser(@Body() reqBody: CreateUserBody, @Param('id') id: string) {
  return { ...body, id: 3 }
}

@ResponseEntry(options)

This is used to add responses entry with proper status code and samples to the operation.

Available Options

  • statusCode [Number or String] - used to specify name
  • description [String] - used to specify description
  • type [String] - used to data type of the parameter
  • schema [Function or String] - used to specify schema of the data type
  • examples [Object] - used to specify examples
  • headers [Object] - used to specify examples
  • <any key name> [any] - entire object will be attached to the specific operation

Syntax

{
  statusCode: number | string,
  description?: string;
  type?: string;
  schema?: Function | string,
  examples?: {
    [key: string]: any;
  };
  example?: any;
  headers?: {
    [name: string]: {
      type: string;
      description?: string;
      [key: string]: any;
    };
  };
  [key: string]: any;
};

Example

Users shall attach responses to the operation.

@ResponseEntry({ statusCode: 200, schema: CreateUserBody, description: 'detailed information about the response' })

User shall add more information along with responses like examples, header information. Users shall add more than one responses to the operations.

@ResponseEntry({ statusCode: 200, schema: CreateUserBody, description: 'detailed information about the response', examples: { 'applications/json': { userId: '<sample data>' } } })
@ResponseEntry({ statusCode: 404, schema: ErrorResponse, description: 'details about the error response', examples: { 'applications/json': { erros: [ { message: 'sample error message' }] } } })

@Model(options)

This is used to specify model schema which will be considered for schema definition generation.

Available Options

  • enabled [Boolean] - used to specify include/ exclude from schema definition generation. Default: true

Syntax

{
	enabled: boolean,
}

Example

@Model() // This is enabled model
@Model({ enabled: true })

@Property(options)

This is used to specify the property which is included in the schema definition generation.

Available Options

  • type [Function] - Used to specify explicit type, By default this will get the declared type
  • description [String] - Used to specify description of the property
  • name [String] - Used to specify explicit name of the property, By default this will get the property name
  • itemType [Function] - Used to specify item data type if it is an array. This is mandatory property if the property type is Array
  • required [Boolean] - Used to specify whether it is required property or not
  • example [any] - Used to specify an example value
  • <any key> [any] - Used to specify custom properties which needs to attach with property definiiton

Syntax

{
	type?: Function;
	description?: string;
	name?: string;
	itemType?: Function;
	required?: boolean;
	example?: any;
	[key: string]: any;
}

Example

@Property({ description: 'Name of the user'})
@Property({ itemType: String, description: 'List of user hobbies' })

Next goals

  • Implement Operation decorator to use without routing-controller decorators
  • Refactor code to sperate two different data sources
  • Implement logging to troubleshot generaiton operation

References

routing-controllers-openapi-extended's People

Contributors

epiphone avatar dhineshpandiyan avatar dependabot[bot] avatar gstamac avatar consense avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.