Swagger; specify two responses with same code based on optional parameter
SwaggerOpenapiSwagger 2.0Swagger Problem Overview
This question is not a duplicate of (https://stackoverflow.com/questions/27844127/swagger-specify-optional-object-property-or-multiple-responses) because that OP was trying to return a 200 or a 400.
I have a GET
with an optional parameter; e.g., GET /endpoint?selector=foo
.
I want to return a 200 whose schema is different based on whether the parameter was passed, e.g.,:
GET /endpoint -> {200, schema_1}
GET /endpoint?selector=blah -> {200, schema_2}
In the yaml, I tried having two 200 codes, but the viewer squashes them down as if I only specified one.
Is there a way to do this?
Edit: the following seems related: https://github.com/OAI/OpenAPI-Specification/issues/270
Swagger Solutions
Solution 1 - Swagger
OpenAPI 2.0
OAS2 does not support multiple response schemas per status code. You can only have a single schema, for example, a free-form object (type: object
without properties
).
OpenAPI 3.x
In OAS3 you can use oneOf
to define multiple possible request bodies or response bodies for the same operation:
openapi: 3.0.0
...
paths:
/path:
get:
responses:
'200':
description: Success
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ResponseOne'
- $ref: '#/components/schemas/ResponseTwo'
However, it's not possible to map specific response schemas to specific parameter values. You'll need to document these specifics verbally in the description
of the response, operation and/or parameter.
Here's a possibly related enhancement request:
Allow operationObject overloading with get-^ post-^ etc
Note for Swagger UI users: Older versions of Swagger UI (before v. 3.39.0) do not automatically generate examples for oneOf
and anyOf
schemas. As a workaround, you can specify a response example
or examples
manually. Note that using multiple examples
require Swagger UI 3.23.0+ or Swagger Editor 3.6.31+.
responses:
'200':
description: Success
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ResponseOne'
- $ref: '#/components/schemas/ResponseTwo'
example: # <--- Workaround for Swagger UI < 3.39.0
foo: bar
Solution 2 - Swagger
I wanted the same thing, and I came up with a workaround that seems to work:
I´ve just defined two different paths:
/path:
(...)
responses:
200:
description: Sucesso
schema:
$ref: '#/definitions/ResponseOne'
(...)
/path?parameter=value:
(...)
responses:
200:
description: Sucesso
schema:
$ref: '#/definitions/ResponseTwo'
(...)
Paths do work on swagger editor. I can even document each option differently and put optional parameters that only may be on the second case toguether, making the API doc much cleaner. Using operationId you may generate cleaner names for the generated API methods.
I´ve posted the same solution here (https://github.com/OAI/OpenAPI-Specification/issues/270) to verify if I am missing something more.
I do understand it is not explicitly allowed/encouraged to do it (neither I found some place explicitly disallowing it). But as a workaround, and being the only way to document an API with this behaviour in the current specification,, looks like an option.
Two problems I´ve found out with it:
- Java code gen URL escapes the "=" sign, therefore it wont work unless you fix this in the generated code. Probably it happens in other code generators.
- If you have more query params it will add an extra "?" and fail;
If those are not blockers, it at least will allow you to document properly such cases and allow testing with swagger editor.