routing-controllers-openapi icon indicating copy to clipboard operation
routing-controllers-openapi copied to clipboard

How can we set parameter `description` and `example`?

Open klassicd opened this issue 5 years ago • 7 comments

Is it currently not possible to set the parameter description and example?

From what I can tell the parameter fields supported are:

  • in
  • name
  • required
  • schema

I'd be interested in contributing if you have an idea in mind how we can support setting a default description and example.

https://swagger.io/specification/#parameterObject

klassicd avatar Mar 13 '19 18:03 klassicd

There's no place to define description and example out of the box, that's correct. Couple of ways around this come to mind:

using QueryParams/Params etc instead of QueryParam/Param:

class MyQueryParams {
  @JSONSchema({ description: 'my ID query parameter' })
  @IsString()
  id: string
}

someHandler(@QueryParams() queryParams: MyQueryParams) {
    // ...
}

my ID query parameter description then ends up in the parameters[0].schema object. We're missing handling for @Params right now so that would need to be added.

adding another decorator , something along the lines of:

function OpenAPIParam(name: string, props: Partial<ParameterObject>) {
  return OpenAPI(schema => {
    const index = schema.parameters.findIndex(
      p => 'name' in p && p.name === name
    )
    if (index > -1) {
      schema.parameters[index] = {
        ...schema.parameters[index],
        ...props
      }
    }
    return schema
  })
}

@OpenAPIParam('id', { description: 'My ID path parameter', example: 1234 })
someHandler(@Param('id') id: number) {
  // ...
}

Now description ends up in parameters[0] - not inside schema like above.

epiphone avatar Mar 14 '19 09:03 epiphone

Any plan about this?

jinker avatar Apr 18 '19 06:04 jinker

No plan, no. Try one of the workarounds outlined above or submit a PR!

epiphone avatar Apr 18 '19 07:04 epiphone

The same problem for me. So far I only have a ugly way.

export function ParamsWithOpenAPI() {
  return (object: object, methodName: string, index: number) => {
    Params()(object, methodName, index);
    const type = Reflect.getMetadata('design:paramtypes', object, methodName)[index];
    const targetName = type.name;
    OpenAPI((source) => {// todo
      const metadatas = (getFromContainer(MetadataStorage)as any).validationMetadatas.filter((validationMetadata) => {
        return validationMetadata.target.name === targetName;
      });

      const schemas = validationMetadatasToSchemas(metadatas, {
        refPointerPrefix: '#/components/schemas/',
        classTransformerMetadataStorage: defaultMetadataStorage,
      });
      const schema = schemas[targetName];
      if (!schema) {
        return source;
      }
      source.parameters = _.chain(schema.properties)
        .toPairs()
        .map(([name, propertyInfo]) => ({
          in: 'path',
          name,
          required: true,
          schema: {
            type: 'string',
          },
          description: propertyInfo.description || '',
        } as ParameterObject))
        .concat(source.parameters as ParameterObject[])
        .reject(({description}) => description === undefined)
        .value();
      return source;
    })(object, methodName, {} as PropertyDescriptor);
  };
}

I create another decorate that use @Params and @OpenAPI.Pass an function that modify the openApi doc to OpenAPI.

And I still look for a better way. looking forward routing-controllers-openapi can solve it.

chianquan avatar Dec 28 '19 09:12 chianquan

which ui for openapi you use ? I use the swagger-ui-dist.It didn't show the QueryParams's description,only an black rectangle and show the demo query using json format.

chianquan avatar Dec 28 '19 10:12 chianquan

There's no place to define description and example out of the box, that's correct. Couple of ways around this come to mind:

using QueryParams/Params etc instead of QueryParam/Param:

class MyQueryParams {
  @JSONSchema({ description: 'my ID query parameter' })
  @IsString()
  id: string
}

someHandler(@QueryParams() queryParams: MyQueryParams) {
    // ...
}

my ID query parameter description then ends up in the parameters[0].schema object. We're missing handling for @Params right now so that would need to be added.

adding another decorator , something along the lines of:

function OpenAPIParam(name: string, props: Partial<ParameterObject>) {
  return OpenAPI(schema => {
    const index = schema.parameters.findIndex(
      p => 'name' in p && p.name === name
    )
    if (index > -1) {
      schema.parameters[index] = {
        ...schema.parameters[index],
        ...props
      }
    }
    return schema
  })
}

@OpenAPIParam('id', { description: 'My ID path parameter', example: 1234 })
someHandler(@Param('id') id: number) {
  // ...
}

Now description ends up in parameters[0] - not inside schema like above.

The second example if very helpful and I think most users might need it. Wouldn't it be great to add it to the package?

lokeshmohanty avatar Nov 26 '20 07:11 lokeshmohanty

Currently, in 2022, this can be done by below line of code:

@OpenAPI({ parameters: [{ name: 'party', description: 'Should be one of [`email`, `wallet`]', in: 'path' }] })

thuyhoang-hvtt avatar Sep 05 '22 07:09 thuyhoang-hvtt