swagger
swagger copied to clipboard
[Feature Request] Multiple response with the same status code
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
Swagger only allows one response per status code, but sometimes we have more than one response body.
Expected behavior
We can work around this in the decorator by:
- Changing the status field type from
number
tonumber | string
- Checking if the
status
already exists - If it exists, we add a space to the response code
Minimal reproduction of the problem
@ApiForbiddenResponse({ type: UnauthorizedTokenException })
@ApiForbiddenResponse({ type: InsufficientRolesException })
What is the motivation / use case for changing the behavior?
I have more than one error response with different Dto
classes using the same status code.
Would you like to create a PR? :)
Would you like to create a PR? :)
Yes I have created a PR resolving the issue.
Any updates?
something new?
+1
Would love to see this merged.
I might be late for this but why don't you use the SchemaObject
interface to document your responses?
@ApiForbiddenResponse({
schema: {
anyOf: refs([
UnauthorizedTokenException,
InsufficientRolesException
])
}
})
@fwoelffel
Hi
I came in while Googleing because I needed a multiple response from swagger.
The multi error response you have attached is resolved, but it does not apply to the 200 success responses. Because the arrangement of "refs" only request "funcion types."
What kind of settings do I need to set to respond to 200 multiple responses?
I can't see anything in browser with Schema Object
like this:
@ApiOkResponse({
schema: { anyOf: [{ $ref: getSchemaPath(UserOrderInfoDto) }] },
})
// or
@ApiOkResponse({
schema: { anyOf: [{ type: getSchemaPath(UserOrderInfoDto) }] },
})
;(
@fwoelffel Hi I came in while Googleing because I needed a multiple response from swagger. The multi error response you have attached is resolved, but it does not apply to the 200 success responses. Because the arrangement of "refs" only request "funcion types." What kind of settings do I need to set to respond to 200 multiple responses? I can't see anything with Schema Object setting like this:
I'm not sure I fully understand your issue, but I'll try to help.
Have you tried with refs
like I did in my example? refs
can be imported from @nestjs/swagger
.
import {
ApiOkResponse,
refs,
} from '@nestjs/swagger';
// ...
@ApiOkResponse({
schema: {
anyOf: refs([
UserOrderInfoDto
]),
},
})
@fwoelffel
Yes, I tried.
However, refs require function array type and my UserOrerInfoDto is Class type, so type error occured.
@fwoelffel Yes, I tried. However, refs require function array type and my UserOrerInfoDto is Class type, so type error occured.
Could you share your UserOrderInfoDto
implementation? Make sure it is a class
and not an interface
.
EDIT: Ok, I'm sorry I didn't realize this earlier. Your DTOs should not be wrapped in an array:
@ApiOkResponse({
schema: {
anyOf: refs(
UserOrderInfoDto
),
},
})
Sorry for misleading you. 😞
Thank you very much! Your code works well and expresses multiple responses well. In fact, the essential problem was that what I was going to designate as a response "schema" was not registered as a "schemas", so swagger showed empty object.
For those who have missed the official document like me, write additional.
If your DTO is not represented or read by an empty object, you must register the DTO through @ApiExtraModels()

Thank you for your help!!
I would like this as well
If it exists, we add a space to the response code
but OpenAPI v3 doesn't allow that :(
Another issue that comes with using multiple @ApiX()
decorators in this way is that we won't be able to implement the following pattern:
@Controller()
@ApiOkResponse({ description: 'fallback ok' })
class SomeController {
@Get('foo1')
foo1() {} // Will have 200 with 'fallback ok' description
@Get('foo2')
foo2() {} // Same as above
@Get('bar')
@ApiOkResponse({ description: 'only this one will appear in the docs for this endpoint' })
bar() {}
}
Isn't this essentially adding multiple response examples to the same swagger path?
I tried the same but nothing will work.
@ApiOkResponse({
schema: {
oneOf: refs(
UpdateDeviceTokenResponse
)
}
})
UpdateDeviceTokenResponse - This will be a class.
@VulchiSarath have you registered UpdateDeviceTokenResponse
? either configuring the nestjs swagger plugin or using @ApiExtraModels(UpdateDeviceTokenResponse)
https://docs.nestjs.com/openapi/types-and-parameters#extra-models
does someone know how to return either UserOrderInfoDto | null
?
this does not work unfortunately..:
@ApiOkResponse({
schema: {
anyOf: refs(
UserOrderInfoDto,
null
),
},
})
What if my responses are just strings? This doesn't seem to work:
@ApiBadRequestResponse({
schema: {
example: 'Response 1',
anyOf: refs(
() => 'Response 1',
() => 'Response 2',
() => 'Response 3'
)
}
})
Try passing a SchemaObject
instead of ReferenceObject
{
status: HttpStatus.NOT_FOUND,
schema: {
anyOf: [
{
title: 'Customer',
description: `The customer couldn't be found in our system, please verify and try again.`,
example: `The customer couldn't be found in our system, please verify and try again.`,
},
{
title: 'Supplier',
description: `The supplier couldn't be found in our system, please verify and try again.`,
example: `The supplier couldn't be found in our system, please verify and try again.`,
},
{
title: 'PartNumbers',
description: `The information provided couldn't be found in the part numbers master, please verify and try again.`,
example: `The information provided couldn't be found in the part numbers master, please verify and try again.`,
},
],
},
},
One solution I try a lot of time to handle. Maybe it can help your guys
export interface IAppError {
name: string
code: string
status: HttpStatus
message: string
}
export const ApiSchemaRes = (schema: IAppError): Type<IError> => {
class SchemaResponse implements IError {
@ApiProperty({ name: 'type', type: 'enum', enum: ErrorType, default: ErrorType.REST })
type: ErrorType
@ApiProperty({ name: 'time', type: 'string', default: new Date().toISOString() })
time: string
@ApiProperty({ name: 'code', type: 'string', default: schema.code })
code: string
@ApiProperty({ name: 'code', type: 'string', default: schema.message })
message: string
}
Object.defineProperty(SchemaResponse, 'name', { writable: true, value: schema.name })
return SchemaResponse
}
export const ApiFailedRes = (...schemas: IAppError[]) => {
return applyDecorators(
ApiResponse({
status: schemas[0].status,
content: {
'application/json': {
examples: schemas.reduce((list, schema) => {
list[schema.name] = { value: schema }
return list
}, {}),
},
},
}),
)
}
Then I add this decorator to any controller I want to
The result will be look like