nestjs / swagger

OpenAPI (Swagger) module for Nest framework (node.js) :earth_americas:
https://nestjs.com
MIT License
1.69k stars 474 forks source link

Add support for Swagger/OpenAPI Extensions #195

Closed skyquartam closed 4 years ago

skyquartam commented 5 years ago

I'm submitting a...


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

Current behavior

There are no decorators for the Open Api Extensions

Swagger Doc

Java Decorator Example

Expected behavior

This is an example of this decorator in Java Swagger module

    @ApiOperation(value = "/ranking/calcio",
            httpMethod = "GET",
            extensions = @Extension(name = "x-amazon-apigateway-integration", properties = {
                    @ExtensionProperty(name = "uri", value = "http://HTTP_ENDPOINT/sportsdata/api/rest/ranking/calcio"),
                    @ExtensionProperty(name = "connectionType", value = "VPC_LINK"),
                    @ExtensionProperty(name = "connectionId", value = "VPC_LINK_ID"),
                    @ExtensionProperty(name = "httpMethod", value = "GET"),
                    @ExtensionProperty(name = "type", value = "http_proxy")
            }))

That produces this output in the swagger.json file:

"/ranking/calcio" : {
      "get" : {
        "tags" : [ "Ranking API" ],
        "summary" : "/ranking/calcio",
        "description" : "",
        "operationId" : "footballRankingRest",
        "parameters" : [ /* ... */],
        "responses" : {
          "200" : {
            "description" : "The football ranking",
            "schema" : {
              "$ref" : "#/definitions/ResponseBean"
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "connectionId" : "VPC_LINK_ID",
          "httpMethod" : "GET",
          "type" : "http_proxy",
          "uri" : "http://HTTP_ENDPOINT/sportsdata/api/rest/ranking/calcio",
          "connectionType" : "VPC_LINK"
        }
      }
    }
]

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

At this time this is blocking because we need this extension in order to use the swagger.json to generate Amazon API Gateway definition files

I did not find any doc on how to create/extend existing decorators, if you point me to the right direction i can try to implement it

Thank you for your amazing work

mikrivorot commented 5 years ago

Some solution can be done locally in the application without changes in nest/swagger

My goal was to add custom swagger parameters to request body (decorator ApiModelProperty)

1) Use {showExtensions: true} in main.ts (necessary for UI, because even if you have custom parameters on back and in json in UI, it will be not renderred without this property):

SwaggerModule.setup('api', app, document, {swaggerOptions: {showExtensions: true}});

2) Create your own decorator and extend metadata in your project file:

import  {ApiModelProperty} from '@nestjs/swagger'

type SwaggerDecoratorParams  = Parameters<typeof ApiModelProperty>;
type SwaggerDecoratorMetadata = SwaggerDecoratorParams [0];
type MyAwesomeMetadata = SwaggerDecoratorMetadata & CustomSwaggerParameters;

export const MyAwesomeDecorator = (params: MyAwesomeMetadata) => {
  return ApiModelProperty(params);
};

class CustomSwaggerParameters {
  'x-ui-test'?: boolean;
}

3) Use it

import {MyAwesomeDecorator as ApiModelProperty}  from "somepath/in/project";

export class TestParameters {
  @ApiModelProperty({minimum: 1, example: 1, 'x-ui-test': true})
  public testParameter: number;
}
andreoav commented 5 years ago

I don't think the solution above works as a @Extension is supposed to work. The property is added to the request object, inside the schema.

This also blocking me from using nest. I need to publish an API and the API gateway needs a custom property in the swagger definition.

gilesmoreno commented 4 years ago

It is not the ideal solution...

import * as _ from 'lodash';

.forEach(document.paths, function(path) { .forEach(path, function(operation) { var extensionForOperation = { 'x-amazon-apigateway-integration': { 'connectionId': 'VPC_LINK_ID', 'httpMethod': 'GET', 'type': 'http_proxy', 'uri': 'http://HTTP_ENDPOINT/sportsdata/api/rest/ranking/calcio', 'connectionType': 'VPCLINK', }, }; .assign(operation, extensionForOperation); }); });

SwaggerModule.setup('swagger', app, document);

CesarBMartinez commented 4 years ago

Hey guys, any news about this issue?

tomchinery commented 4 years ago

@CesarBMartinez I'll take a look into it and see if I can raise a PR.

kamilmysliwiec commented 4 years ago

Added in 4.3.0. We're tracking PR to the docs here https://github.com/nestjs/docs.nestjs.com/pull/1021

andreoav commented 4 years ago

@kamilmysliwiec this does not work if the extension value is a not an object.

@ApiExtension('x-auth-type', 'none') results in a wrong json output... it spreads the none string.

kamilmysliwiec commented 4 years ago

cc @tomchinery Can you take a look?

davidlaym commented 4 years ago

For root level vendor extensions should I create a new issue? I'm trying to integrate redoc with tag-groups and those are exposed as root level vendor extensions:

https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#redoc-vendor-extensions

andreoav commented 4 years ago

@tomchinery any news about the problem with values as strings?

tomchinery commented 4 years ago

@andreoav @kamilmysliwiec Apologies I've been away for the past week. I'll take a look at this today.

CesarBMartinez commented 4 years ago

Hi @tomchinery any news about the issue reported by @andreoav?

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.