Code Monkey home page Code Monkey logo

swagger's Introduction

Nest Logo

A progressive Node.js framework for building efficient and scalable server-side applications.

NPM Version Package License NPM Downloads CircleCI Coverage Discord Backers on Open Collective Sponsors on Open Collective

Description

OpenAPI (Swagger) module for Nest.

Installation

$ npm i --save @nestjs/swagger 

Quick Start

Overview & Tutorial

Migration from v3

If you're currently using @nestjs/swagger@3.*, note the following breaking/API changes in version 4.0.

The following decorators have been changed/renamed:

  • @ApiModelProperty is now @ApiProperty
  • @ApiModelPropertyOptional is now @ApiPropertyOptional
  • @ApiResponseModelProperty is now @ApiResponseProperty
  • @ApiImplicitQuery is now @ApiQuery
  • @ApiImplicitParam is now @ApiParam
  • @ApiImplicitBody is now @ApiBody
  • @ApiImplicitHeader is now @ApiHeader
  • @ApiOperation({ title: 'test' }) is now @ApiOperation({ summary: 'test' })
  • @ApiUseTags is now @ApiTags

DocumentBuilder breaking changes (updated method signatures):

  • addTag
  • addBearerAuth
  • addOAuth2
  • setContactEmail is now setContact
  • setHost has been removed
  • setSchemes has been removed (use the addServer instead, e.g., addServer('http://'))

The following methods have been added:

  • addServer
  • addApiKey
  • addBasicAuth
  • addSecurity
  • addSecurityRequirements

Support

Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.

Stay in touch

License

Nest is MIT licensed.

swagger's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swagger's Issues

ApiReponse with type is an Advanced Types

Hi,

I have an generic class who is return on all my request

import { ApiModelProperty } from '@nestjs/swagger';

export class ServerApiResponse<T> {
  
  @ApiModelProperty()
  value: T;
  
  @ApiModelProperty({ type: Number })
  pages: number;


  @ApiModelProperty({ type: Number })
  page: number;

  @ApiModelProperty({ type: Number })
  maxByPage: number;


  @ApiModelProperty({ type: Number })
  count: number;

  @ApiModelProperty({ type: Object })
  error: any;
}

And on my endpoint i have add

@ApiResponse({
    status: 200,
    description: '',
    type: ServerApiResponse<PatientCaretrackPopulatedOutput[]>
  })

But i have this error Error TS2348: Value of type 'ServerApiResponse' is not callable.

So i tried this

@ApiResponse({
    status: 200,
    description: '',
    type:  new ServerApiResponse<PatientCaretrackPopulatedOutput[]>()
  })

But when i launch swagger i have no description of response returned.

It's possible to do this ?

Thx

Tutorial seems to be broken

I'm having issues with initializing swagger module.

My server.ts file:

import { NestFactory } from '@nestjs/core';
import { json } from 'body-parser';
import { ApplicationModule } from './modules/app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.use(json());

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('/api', app, document);

  await app.listen(3000);
}
bootstrap();

And i have following result:

[Nest] 2632   - 2017-12-6 19:38:42   [ExceptionHandler] app.use() requires a middleware function
TypeError: app.use() requires a middleware function
    at Function.use (D:\Learning\nest\project\node_modules\express\lib\application.js:210:11)
    at NestApplication.use (D:\Learning\nest\project\node_modules\@nestjs\core\nest-application.js:103:22)
    at exceptions_zone_1.ExceptionsZone.run (D:\Learning\nest\project\node_modules\@nestjs\core\nest-factory.js:107:48)
    at Function.run (D:\Learning\nest\project\node_modules\@nestjs\core\errors\exceptions-zone.js:16:13)
    at Proxy.args (D:\Learning\nest\project\node_modules\@nestjs\core\nest-factory.js:106:54)
    at Function.setup (D:\Learning\nest\project\node_modules\@nestjs\swagger\swagger-module.js:11:13)
    at D:\Learning\nest\project\server\server.ts:17:17
    at Generator.next (<anonymous>)
    at fulfilled (D:\Learning\nest\project\server\server.ts:4:58)
    at <anonymous>
(node:2632) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Unhandled Runtime Exception.
(node:2632) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero
 exit code.

Line 17 is where i call SwaggerModule.setup('/api', app, document)

Use example

Hi,all

Can some one provide some use example? plz ;)

Error when swagger is used in a hybrid app

The swagger module throws an error when used in a hybrid app. Possibly because the microservice is marked as a controller but has no http methods?


TypeError: Cannot read property 'path' of undefined
    at lodash_1.groupBy (/home/james/projects/paladinjs/paladinjs-core/node_modules/@nestjs/swagger/swagger-transformer.js:6:83)
    at arrayAggregator (/home/james/projects/paladinjs/paladinjs-core/node_modules/lodash/lodash.js:518:34)
    at Function.groupBy (/home/james/projects/paladinjs/paladinjs-core/node_modules/lodash/lodash.js:4862:16)
    at SwaggerTransformer.normalizePaths (/home/james/projects/paladinjs/paladinjs-core/node_modules/@nestjs/swagger/swagger-transformer.js:6:40)
    at SwaggerScanner.scanApplication (/home/james/projects/paladinjs/paladinjs-core/node_modules/@nestjs/swagger/swagger-scanner.js:15:50)
    at Function.createDocument (/home/james/projects/paladinjs/paladinjs-core/node_modules/@nestjs/swagger/swagger-module.js:6:46)
    at Function.<anonymous> (/home/james/projects/paladinjs/paladinjs-core/dist/bin/paladin.js:45:53)
    at Generator.next (<anonymous>)
    at /home/james/projects/paladinjs/paladinjs-core/dist/bin/paladin.js:7:71
    at __awaiter (/home/james/projects/paladinjs/paladinjs-core/dist/bin/paladin.js:3:12)
    at Function.init (/home/james/projects/paladinjs/paladinjs-core/dist/bin/paladin.js:40:16)
    at /home/james/projects/paladinjs/paladinjs-core/dist/bin/startup.js:20:27
    at Generator.next (<anonymous>)
    at fulfilled (/home/james/projects/paladinjs/paladinjs-core/dist/bin/startup.js:4:58)
    at process._tickCallback (internal/process/next_tick.js:109:7)
    at Module.runMain (module.js:607:11)
    at run (bootstrap_node.js:427:7)
    at startup (bootstrap_node.js:151:9)
    at bootstrap_node.js:542:3

Here is how swagger is used.

        try {
            const documentBuilder = new DocumentBuilder();
            const doc = SwaggerModule.createDocument(app, documentBuilder.build());
            httpserver.use('/swagger', swaggerUI.serve, swaggerUI.setup(doc));
            httpserver.use('/api-docs', (req, res, next) => res.send(doc));
        } catch (error) {
            console.error(error);
        }

Here is the service

import { MessagePattern } from '@nestjs/microservices';
import { Controller, Inject } from '@nestjs/common';
import { LOGGER_TOKEN, ILogger } from '../logger/logger';
import { USER_STORE_TOKEN, UserStore } from './user-store';

import { GET_ORGS } from './user.service.proxy';

@Controller()
export class UsersService {

    constructor( @Inject(USER_STORE_TOKEN) private store: UserStore,
                 @Inject(LOGGER_TOKEN) private logger: ILogger) {
    }

    @MessagePattern(GET_ORGS)
    async getOrganisations() {
        let orgs = await this.store.getOrganisations();
        if (!orgs) {
            await this.store.addOrganisation('default');
            orgs = await this.store.getOrganisations();
        }
        return orgs;
    }
}

Preserve auth token in localStorage

Hello, currently after pressing the authorize button JWT token sent along with requests until a user refreshes a page.

After each page refresh user should authorize again.

I think it's a bug and token should be saved in localStorage or sessionStorage (for security reasons).

But at least I want to have a checkbox "remember me" in authorization modal window so I can easily use just Swagger without any additional tools like Modheader.

[1.2.0] SyntaxError: Unexpected token )

The following is the error log after running the sample code:

/tmp/product-catalog-ts/node_modules/@nestjs/swagger/decorators/api-operation.decorator.js:21
    ),
    ^

SyntaxError: Unexpected token )
    at createScript (vm.js:56:10)
    at Object.runInThisContext (vm.js:97:10)
    at Module._compile (module.js:542:28)
    at Module._extensions..js (module.js:579:10)
    at Object.require.extensions.(anonymous function) [as .js] (/tmp/product-catalog-ts/server/node_modules/ts-node/src/index.ts:392:14)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)

The problem seems to be caused by trailing commas and is not present in the release 1.1.4

Is this an issue with my TypeScript setup as the trailing commas should be allowed?!

ApiModelProperty groups

Hi,

thank you with your contribution of nest and swagger.

I have a question, is there a possibility that the properties with the decorator @ApiModelProperty support groups?

Similar to class-validator groups https://github.com/typestack/class-validator#validation-groups.

export class MyClass {

    @ApiModelProperty({ groups: ["edit"] })
    id: string;

    @ApiModelProperty({ groups: ["edit", "create"] })
    name: string;

    @ApiModelProperty({ groups: ["edit", "create"] })
    description: string;

}

in controller

@ApiImplicitBody({ required: true, type: MyClass, name: "name", groups:["create"]  })
//or
@ApiResponse({ status: 200, description: "OK", type: MyClass, groups:["edit"] })

or is there an alternative to not show all the attributes in a response or body? Currently I am creating additional classes.

Thanks

Maximum callstack exceeded on nested properties of same class

I have the following class definition which i have decorated with the @ApiModelProperty decorator. I am facing with maximum callstack.

export class CreateCatDto {
    @IsString() readonly name: string;

    @IsInt() readonly age: number;

    @IsString() readonly breed: string;

    @ApiModelProperty({
        type: CreateCatDto, // <------ This is causing the error in my opinion
        isArray: true,
        description: 'Array of kittens'
    })
    readonly litter: CreateCatDto[]; 
}

Use decorator 'ApiImplicitBody' compile error.

Hi,
I used decorator ApiImplicitBody from ''@nestjs/swagge<v1.1.4>" in controller like this:

@ApiImplicitBody({ name: 'username', description: 'some', required: true, type: 'string' })
@Post('login')
@Bind(Body())
login(body) {}

But when I want to start the project throw compile error:

(node:18200) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError
(node:18200) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I have no idea why this hanppend. Other decorator works well.

Please... Oh Please! Add an easy support for SwaggerUI themes (custom css)

The default theme looks really beautiful but the UX is a disaster.
When you have 15+ (I can't believe that anybody really think that's enough) API methods with documentation, it becomes too easy to get lost in all those huge UI blocks.
I believe we all want to have a more compact view.
Just look at the gif.
Can you quickly get an overview of the API?

badui

No, you can't. )

Yes, I know you can collapse sections. But that is has nothing to do with the real-life usage.

ApiModelProperty decorator on a ManyToOne relationship looses type on one side

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

When defining a @ManyToOne with @ApiModelProperty the relation type gets lost in swagger definition and is set as type: ''

UserEntity:
      ...
      app:
        type: ''
      ...

Expected behavior

Swagger definition contains right type on both ends of relation

UserEntity:
      ...
      app:
        type: object
        $ref: '#/definitions/AppEntity'
      ...

Minimal reproduction of the problem with instructions

@Entity()
export class AppEntity {
  @ApiModelPropertyOptional({ type: String })
  @PrimaryGeneratedColumn('uuid')
  id: string

  @ApiModelProperty()
  @Column({ length: 256, nullable: true, default: null })
  name: string

  @ApiModelProperty({ type: UserEntity, isArray: true })
  @OneToMany(type => UserEntity, user => user.app)
  users: UserEntity[]
}
@Entity()
export class UserEntity {
  @ApiModelPropertyOptional({ type: String })
  @PrimaryGeneratedColumn('uuid')
  id: string

  @ApiModelProperty()
  @Column()
  name: string

  @ApiModelProperty({ type: AppEntity })
  @ManyToOne(type => AppEntity, app => app.users)
  app: AppEntity
}

ends up with swagger definition

  UserEntity:
    type: object
    properties:
      id:
        type: string
      name:
        type: string
      app:
        type: ''
    required:
      - name
      - app
  AppEntity:
    type: object
    properties:
      id:
        type: string
      name:
        type: string
      users:
        type: array
        items:
          $ref: '#/definitions/UserEntity'
    required:
      - name
      - users

What is the motivation / use case for changing the behavior?

@ManyToOne / @OneToMany should create correct definition

Environment


    "@nestjs/common": "^4.6.5",
    "@nestjs/core": "^4.6.5",
    "@nestjs/microservices": "^4.6.5",
    "@nestjs/swagger": "^1.1.4",
    "@nestjs/testing": "^4.6.1",
    "@nestjs/typeorm": "^2.0.0",
    "@nestjs/websockets": "^4.6.5",
    "typeorm": "^0.1.16",
    "typescript": "^2.7.2" 

ApiModelProperty example field

It would be nice to have an optional example field, allowing to customize the output on the example value (i.e: at this moment, any Date type on Model has to be defined as String on ApiModelProperty, and this issue is reflected as "string" on the example). Other case is when you want to suggest a list of default values.

I've tested on Swagger editor and it works: https://imgur.com/a/wolXA

The same field could be on ApiImplicitBody & ApiResponse.

Array in query string parameters

Per the swagger spec, query string params can be specified as an array by using type: "array" along with items: [type of array items]. This doesn't appear to be possible with the existing ApiImplicitQuery options. Is there another way or recommended approach for how to support query string params that are arrays?

Thanks!

How to provide JSON response schema?

@ApiResponse({ status: 201, description: 'Creates new player object.' })

Only (I think) allows for the status and description (plus some other fields). How can I implicitly or explicitly (^^) force SwaggerModule to show the JSON that will be returned?

@ApiModelProperty - Disable option when extends

Hello!

I want to extend basic model, something like "class UpdateUserModel extands UserModel"
And i want to hide some properties like "id" or "email" for documentation in UpdateUserModel

Now i find only one way - don't extends basic class and copy shared properties and don't copy excluded properties.

Unable to generate parameter info from class members

Check out the project over at https://github.com/xeoneux/nexa

I'm unable to generate the parameters in Swagger doc even after providing the correct decorators on class members

Example of CreateUserDto:

import {ApiModelProperty} from '@nestjs/swagger';
import {IsEmail, IsNotEmpty, IsString, MaxLength} from 'class-validator';

export class CreateUserDto {
  @IsString() @ApiModelProperty()
  name: string;

  @ApiModelProperty() @IsEmail()
  email: string;

  @IsNotEmpty() @MaxLength(20) @ApiModelProperty()
  password: string;
}

Example of UserController:

@ApiUseTags('user') @Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {}
  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.userService.create(createUserDto);
  }
}

Example of configuration:

(async () => {
  const app = await NestFactory.create(ApplicationModule);
  const options = new DocumentBuilder()
                      .setTitle('Nexa')
                      .setVersion('1.0')
                      .setBasePath('/v1')
                      .setDescription('Nexa API description')
                      .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('/api', app, document);
  app.useGlobalPipes(new ValidationPipe());
  app.setGlobalPrefix('v1');
  app.listen(config.PORT);
})();

The code is available at https://github.com/xeoneux/nexa

Support dynamic type definition

I would like to be able to do :

@ApiResponse({ status: HttpStatus.OK, description: 'Returns token and logged user', type: { user: User, token: String } })
  @Post('login')
  public async login( @Body() loginInformation: { email: string, password: string }) {
    const user = await this.userService.login(loginInformation.email, loginInformation.password);
    const token = await this.authService.createToken(user);
    return { user, token };
  }

Sadly both types are not taken into account in Swagger.

Support for @Body('property') decorator

Hi,

I've been playing around with the Swagger module. Looks great!

I did notice that it doesn't seem to support the @Body('property') decorator.

  @Post('login')
  public async login(
    @Body('email') email: string,
    @Body('password') password: string
  ): Promise<AccessToken> {
    return this.userService.login(email, password);
  }

Ends up generating a Swagger API without any parameters for login.

Defining ApiResponse at controller level doesnt work properly

For example, i have UsersController:

@ApiUseTags('users')
@ApiResponse({ status: 403, description: 'Forbidden. Please provide valid bearer token.' })
@Controller('users')
export default class UsersController {
...
  @Get()
  async getAllUsers() {
  ...
  @ApiOperation({ title: 'Create new user' })
  @ApiResponse({ status: 200, description: 'User has been successfully created.', type: CreateUserResponce })
  @ApiResponse({ status: 400, description: 'Request did not passed validation.' })
  @Post()
  @UsePipes(new ValidationPipe())
  async createUser(@Body() user: CreateUserDto): Promise<CreateUserResponce> {
  ...

In the swagger ui i have this:
image
Now we see, that if i don't define @ApiResponse for method, like in getAllUserseverything works as expected, but if i define @ApiResponse at least once, controller-defined @ApiResponse getting overridden.

[Help] ApiResponse, getAll, list of a type

Hello guys !

I'm nest with NestJS, and new with TS also. I'm trying to implement a basic API, and I have trouble to use the @ApiResponse while defining a list.

I was looking at this issue: #41
But I clearly don't understand what's happening.

I'm trying something like this:

import { ApiModelProperty } from '@nestjs/swagger';

export class Location {
  @ApiModelProperty()
  id: string;

  @ApiModelProperty()
  name: string;
}
  @Get()
  @ApiResponse({
    type: Location[],
  })
  findAll() {}

And I don't know how to configure the type to understand that I want a list of Location.

Thank you !

Using the dto class and @Body decorator does not work as expected.

The code:

DTOs:

import {
  ApiModelProperty,
} from '@nestjs/swagger';

import { UserDto } from './user.dto';

export class CreateUserDto extends UserDto {

  @ApiModelProperty()
  readonly password: string;

  @ApiModelProperty()
  readonly confirmPassword: string;
}
import {
  ApiModelProperty,
  ApiModelPropertyOptional,
} from '@nestjs/swagger';


export class UserDto {

  @ApiModelPropertyOptional()
  readonly firstName?: string;

  @ApiModelPropertyOptional()
  readonly lastName?: string;

  @ApiModelProperty()
  readonly email: string;
}

Controller:

@ApiUseTags('users')
@Controller('users')
export class UsersController {

  constructor(private readonly usersService: UsersService) {}

  /**
   * Creates a new User (register)
   *
   * @param createUserDto
   * @return Promise<void>
   */
  @Post()
  @ApiOperation({ title: 'Create a new User' })
  @ApiResponse({
    status: HttpStatus.CREATED,
    description: 'The record has been successfully created.',
  })
  @ApiResponse({
    status: HttpStatus.BAD_REQUEST,
    description: 'confirm password doesn\'t match the password, or the payload is invalid',
  })
  @ApiResponse({
    status: HttpStatus.CONFLICT,
    description: 'Email already in use',
  })
  @ApiResponse({ status: HttpStatus.FORBIDDEN, description: 'Forbidden.' })
  @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: 'Unauthorized.' })
  async createUser(@Body() createUserDto: CreateUserDto) {
    await this.usersService
      .create(createUserDto)
      .catch(this._handleError);
  }

  / * <...> */

}

The result:

screenshot 2018-03-22 03 05 24


However, using the following is fixing the Swagger UI:

  @ApiImplicitBody({
    name: 'role data',
    type: CreateUserDto,
  })

ApiResponse hierarchy

First of all, nice work integrating Swagger, I'll use it on my next project.

This is a possible feature. At this moment, if you use ApiResponse decorator at controller level, when you add additional ApiResponse at method level, you loose the main api responses configured before.

Example
dummy.controller.ts

@Controller('dummy')
@ApiResponse({ status: 400, description: 'Bad request'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
export class DummyController {
    @Post()
    @ApiResponse({ status: 201, description: 'Created'})
    public getItems(@Req() req, @Res() res) {
        ...
    }
}

In this case, Swagger only displays the status 201 as response. Maybe it would be more helpful to inherit main controller responses, displaying 201, 400 & 403.

What do you think?

enum type support

It looks like typescript enum types are not supported yet
in rsponse definition i set ConfigModel as type response like this

// model definition
export enum EnvConfig {
  PROD,
  DEV
}
export class ConfigModel {
  @IsString()
  @ApiModelProperty()
  domain: string;

  @IsInt()
  @ApiModelProperty()
  port: number;

  @ApiModelProperty()
  env: EnvConfig;
}

// controller
  @Post('api')
  @ApiResponse({status: 200, type: ConfigModel})
  api(@Body() data: ConfigModel): ConfigModel {
    return data;
  }

in the swagger-ui docs it's represented as number:

ConfigModel {
  domain: string
  port: number
  env: number
}

it's not supported or I did something wrong ?

I'm willing to help and do PR with this feature if anyone will point me in right direction

btw: grate job with the nestjs, i think it's gonna by the best choice for node developers

ApiModelProperty always sets required:true when custom type provided

When you define something like this:

@ApiModelProperty({required: false, type: MyCustomModel})
myProperty: MyCustomModel;

the swagger will always result this property as required: true
it's only for custom models, works ok for all other types

I did quick debugging and it's simple to fix
problem is in line 101 inside api-parameters.explorer.ts file
https://github.com/nestjs/swagger/blob/master/lib/explorers/api-parameters.explorer.ts#L101

return { name: key, $ref };

should be:

return { ...metadata, name: key, $ref };

hope you can include this quick fix on next update

Lodash as a dependency instead of a peer dependency

Is it possible to make lodash a dependency instead of a peer dependency? On some teams lodash is used, but on others you might use Ramda, and not want to have both available to developers for consumption.

MIME-Types for produces and consumes are created twice

When creating a swagger documentation, i get the following error in Swagger-Editor:

Schema error at paths['/health'].get.consumes
should NOT have duplicate items (items ## 0 and 1 are identical)

How to Reproduce

As a minimal example i used this method:

@Controller()
export class HealthController {

    @ApiResponse({ status: HttpStatus.OK})
    @Get("health")
    public async health() {
        return { status: "OK" };
    }
}

What do you expect?

As i did not use the ApiProduces decorator, i expect the default application/json MIME-Type to be used.

What actually happens?

I get the following output in swagger:

paths:
  /health:
    get:
      responses:
        '200':
          description: when the server is reachable
      produces:
        - application/json
        - application/json
      tags:
        - health
      consumes:
        - application/json
        - application/json

As you can see the produces and consumes are there twice.
Also, when defining a custom MIME-Type with @ApiProduces("text/csv"), i have the custom MIME-Type, but also application/json in the swagger docs.

produces:
        - application/json
        - text/csv

Bug with nestjs on mode JavaScript (Babel)

i have node 8.9.0

(node:7074) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property '0' of undefined
(node:7074) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

swagger middleware

In our project we are using swagger-express-mw to, on the one hand, describe our API and get an out-of-the box API documentation, and on the other hand, getting the validation magically against our swagger definition.

By cross reading the code I am a bit confused on how this could incorporate since it is written as a "module" and not as a "middleware" which I thought it should since it should have access to req/res beforehand. Is this module meant to be something like the swagger-express-mw that does all the "magic" with, routing, parameter handling...? And if so, how is it initialized? And even better... do you support also swagger definitions written in yaml?

Support "format" in ApiModelProperty and correct default Date format

See specification for Data Types

Primitives have an optional modifier property: format

This would be very usefull for Date as it will be transported as "string".
So please add format property to ApiModelProperty.

Example class:

class Event {
    @ApiModelProperty({ format: 'password' })
    mySecret: string;

    @ApiModelProperty()
    myDate: Date;
}

should generate:

"definitions": {
  "Event": { 
    "type": "object",
    "properties": {
      "mySecret": { "type": "string", "format": "password" },
      "myDate": { "type": "string", "format": "date-time" } // Date schould get this format by default
    }
  }
}

Is possible to define multiple ApiImplicitHeader with less boilerplate?

{
  ...
  @ApiImplicitHeader({ name: 'X-API-Key' })
  @ApiImplicitHeader({ name: 'X-Latitude' })
  @ApiImplicitHeader({ name: 'X-Longitude' })
  @ApiOperation({ title: 'Allows sign up or register a new user.' })
  @Post('register')
  async register(@Body() body: RegisterDto) {
  ... 
}

It would be nice to accept an array of options or be able to define it on the controller for all methods?

@ApiModelProperty() doesn't work with a <TEntity>

I've made a generic Controller like the following:

export class BaseController<T extends BaseEntity>{
	constructor(private readonly IBaseService: IBaseService<T>) {}

	@Post()
	@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
	async create(@Body() entity: T): Promise<number> {
		return this.IBaseService.create(entity);
	}
}

and I've extended the controller:

@ApiUseTags('users')
@Controller('users')
export class UsersController extends BaseController<User>{
	constructor(private readonly usersService: UsersService) {
		super(usersService)
	}
}

where User:

@Entity('users')
export class User extends BaseEntity{

  @Column({ length: 50 })
  @ApiModelProperty()
  readonly name: string;

  @Column({ length: 50 })
  @ApiModelProperty()
  readonly age: number;
  
  @Column({ length: 50 })
  @ApiModelProperty()
  readonly favouriteColor: number;

  constructor(o: Object) {
    super();
    Object.assign(this, o);
  }
}

*Base Entity is class that with an id for all the classes (it also has the @ApiModelProperty decorator)

But my Swagger documentation does not show the model information.

ApiUseTags decorator don't work on Method

I'm submitting a...


[ ] Regression 
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Minimal reproduction of the problem with instructions

I'm trying to tag just on one method of my controller but it seems not working.

(On the doc: ApiUseTags() | Method / Controller)

import { Get, Controller } from '@nestjs/common';
import { ApiUseTags } from '@nestjs/swagger';

@Controller()
export class AppController {
  @Get()
  @ApiUseTags('admin') // there is no effect in swagger
  ping(): string {
    return 'pong';
  }
}

But on controller this works perfect.

Environment


@nestjs/common@^4.5.9
@nestjs/core@^4.5.10
@nestjs/swagger@^1.1.4
reflect-metadata@^0.1.10
 
For Tooling issues:
- Node version: v8.9.4
- Platform:  Mac

Others:
- yarn

support /:id([0-9]+)

if route path using regexp like /:id([0-9]+), the swagger curl url will be /{id([0-9]+)}, and the request returns 404

Automatically detect optional @Query

Am I right in thinking that you could look for a ? on the query function parameter to denote that it is optional, and pick this up to set the required value on the swagger document?

It would be nicer than having to add decorators like @ApiImplicitQuery({name:'offset',required:false}) to the method I think. What do you reckon?

Thanks :)

"setGlobalPrefix" value isnt used in generated Swagger Doc

If you are setting a specific string via the 'setGlobalPrefix' method when you bootstrap your app, the generated Swagger documentation doesn't seem to have this string as part of the URL in the various 'POST' and 'GET' endpoints. For example, trying to 'execute' the Swagger endpoint would fail b/c the URL isnt correct.

In my case, I would expect the URL to be "/api/cats" but the Swagger doc has it as just "/cats".

async function bootstrap() {
    const app = await NestFactory.create(ApplicationModule);

    // Prepend 'api' to every route
    app.setGlobalPrefix("api");

    // Swagger
    const options = new DocumentBuilder()
    .setTitle("My Test API")
    .setDescription("This is a test")
    .setVersion("1.0")
    .build();
    const document = SwaggerModule.createDocument(app, options);
    SwaggerModule.setup("/docs", app, document);

    await app.listen(5001, () => {
        console.log("Typescript Nest app & Express server running on port 5001");
    });
}

@ApiBearerAuth() does not work on Method level

image
image
As title said, the @ApiBearerAuth() decorator does not work properly on method level. It does work correctly on Controller level. The documentations states that the decorator can work on either Method or Controller level. I was just wondering if this's a bug or I didn't implement it correctly.

image
Worked on Controller level

UI won't acknowledge required parameter value

I am trying to use the swagger ui. it works as expected when a data model is provided for the parameters.

However, when there are route param set via decorators @get(':id'), entering a value does not satisfy the required validation

the field input takes on the styling of an empty required field and you cannot execute the request regardless of there being a value entered in the input

Setting Example data

Hello,
Is there a decorator for setting the example values for swagger as seen below?

image

Thanks.

Registering custom decorators

I have a custom decorator for pagination using query strings but I have not been able to get Swagger to pick them up

// pagination.decorator.ts
import {createRouteParamDecorator} from '@nestjs/common';
import config from 'config';
import {Request} from 'express';
import {PaginationOptions} from './pagination.model';

export const Pagination: Function = createRouteParamDecorator(
  (_: string, req: Request): PaginationOptions => {
    req.query.limit = (typeof req.query.limit === 'number') ?
      req.query.limit :
      parseInt(req.query.limit, 10) || config.pagination.size;

    req.query.page = (typeof req.query.page === 'number') ?
      req.query.page :
      parseInt(req.query.page, 10) || 1;

    if (req.query.limit > config.pagination.max) {
      req.query.limit = config.pagination.max;
    } else if (req.query.limit < config.pagination.min) {
      req.query.limit = config.pagination.min;
    }

    const limit: number = req.query.limit;
    const page: number = req.query.page;

    return {
      limit,
      page
    };
  }
);

// pagination.model.ts
import {ApiModelPropertyOptional} from '@nestjs/swagger';

export class PaginationOptions {
  @ApiModelPropertyOptional() public readonly limit: number;
  @ApiModelPropertyOptional() public readonly page: number;
}

// documents.controller.ts
....
  @Get()
  @ApiResponse(swagger.NOCONTENT)
  @ApiResponse(swaggerWithType(swagger.OK, Document))
  public async httpGetAll (
    @Pagination() pagination: PaginationOptions
  ): Promise<PaginateResult<Role>> {
    return this.documentService.readAll(pagination);
  }
....

OAuth2, inForm type, custom endpoint definition

Hello,

I'm trying to include some additional paramters mostly in relation to OAuth 2 specification.
https://swagger.io/docs/specification/authentication/oauth2/

With actual state there is no possiblity to include custom parameters type:
@ApiImplicitParam({name: 'grant_type', type: 'formData'})
As it defaults to 'path', could you allow to include any other without fallback to default one ?

Even so, sometimes would be great to just no use any of provided decorators, but simply kind of one
ApiCustom(CustomDefinitions.SwaggerEndpointDefinition) where nest swagger will not generate any definition for endpoint but simply use pure provided definition.

bug - using required in ApiModelProperty decorator

When using the decorator ApiModelProperty in the following way:

export class CreateCatDto {
  @ApiModelProperty({ type: String, required: true })
  @IsString()
  readonly name: String;

  @ApiModelProperty({ type: Number, required: true })
  @IsInt()
  readonly age;

  @ApiModelProperty({ type: String, required: true })
  @IsString()
  readonly breed;
}

(I just added the property required to the swagger example https://github.com/nestjs/nest/blob/master/examples/11-swagger/src/modules/cats/dto/create-cat.dto.ts)

it should add the properties name, age & breed to the required array of the parent in the swagger doc.

expected:

"CreateCatDto": {
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "age": {
            "type": "number"
        },
        "breed": {
            "type": "string"
        }
    },
    "required": [
        "name",
        "age",
        "breed"
    ]
}

actual

"CreateCatDto": {
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "required": true
        },
        "age": {
            "type": "number",
            "required": true
        },
        "breed": {
            "type": "string",
            "required": true
        }
    }
}

Feature Request: Provide simple way to automatically download JSON docs

There have been a couple previous questions asked about obtaining the swagger documentation in JSON format (see #21 and #57), and responses to these issues show how to add code to serve the JSON or save it to a file.

I think it would be a great improvement if the SwaggerModule could simply serve the JSON for any doc without any additional code based on an additional path param or query string param in the URL. For example, if you set up your documentation like this:

 SwaggerModule.setup('/api', app, document);

Then maybe by getting /api/json or /api?json or /api?json=true, it would serve the docs in JSON format instead of the HTML version.

This could be enabled automatically for any doc, and existing projects using @nestjs/swagger would gain this feature by upgrading to a new release without making any code changes at all. :)

@ApiProduces doesn't work for controller

In docs it says that @ApiProduces decorator can be applied to a controller.

@ApiResponse({
    status: HttpStatus.BAD_REQUEST,
    description: `Bad request`,
    type: ErrorResponseDTO
})
@Controller('/wallet')
...

But in docs I see nothing but the ErrorResponseDTO listed in models.
I expected to see an example of response with status code 400 somewhere either in the controller section or within endpoins' sections.

Thanks.

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.