Swagger; specify two responses with same code based on optional parameter - swagger

This question is not a duplicate of (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

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

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.

Related

How to display all of the oneOf schemas in Swagger UI?

I have an OpenAPI document where an endpoint uses oneOf for the request body (this endpoint has 2 possible different schemas). In Swagger UI, I can only see one of the schemas where the endpoint is displayed, which I understand is normal. How could I display the other schema or link it, so I can access it easily?
The Schema tab in Swagger UI displays all subschemas of oneOf and anyOf schemas:
To reflect the alternatives on the Example Value tab, you'll need to manually define multiple request body examples, one for each schema. This will add a dropdown to Swagger UI so that the users can switch between the examples.
paths:
/something:
post:
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Foo'
- $ref: '#/components/schemas/Bar'
examples:
fooExample:
summary: An example of Foo data
value:
foo: hello
barExample:
summary: An example of Bar data
value:
bar: 123
I think there was an existing feature request to generate multiple examples for oneOf/anyOf subschemas automatically, but I can't find it. Feel free to submit a feature request yourself.

Swagger reusing examples showing weird $$ref element

I wrote a swagger specification Yaml file and in the components section I have:
examples:
companyExample:
company:
id: uNiquEiD
name: Company Name
I use this companyExample in the response as following:
example:
$ref: '#/components/examples/companyExample'
Here is the output:
So what is this extra "$$ref": "#/components/examples/companyExample" is it a bug? How can I remove it?
The example keyword (not to be confused with multiple exampleS) does not support $ref. The whole example value must be specified inline:
example:
company:
id: uNiquEiD
name: Company Name
To $ref an example defined in #/components/examples, you'll need to use the examples keyword. examples can be used in parameters, request bodies, response bodies and response headers but NOT in schemas. In other words, examples can be used
alongside schema but not inside schema.
For instance, to $ref an example as a response example, you would use the following. Note that the example definition uses the value keyword to wrap the actual example value. (The example definition in your original question is not valid because of the missing value.)
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Company'
examples:
companyExample:
$ref: '#/components/examples/companyExample'
components:
examples:
companyExample:
summary: Sample company data
value:
# The actual example value begins here
company:
id: uNiquEiD
name: Company Name
Note for Swagger UI users: Support for multiple examples is available in Swagger UI 3.23.0+ and Swagger Editor 3.6.31+.

OpenAPI/Swagger: multiple paths with same structure but different path parameters type [duplicate]

I'm trying to turn the Atom Publishing Protocol (RFC5023) in to a Swagger / OpenAPI spec to exercise writing those specs.
I ran into the following problem: in Atom there are different types of URIs, e.g. Collection and Member URIs.
My idea was to document it like this:
paths:
/{CollectionURI}:
get:
summary: List Collection Members
...
post:
summary: Create a Resource
...
parameters:
- $ref: "#/parameters/CollectionURI"
/{MemberURI}:
get:
summary: Retrieve a Resource
...
parameters:
- $ref: "#/parameters/MemberURI"
When I do that, swagger-editor claims that
Equivalent path already exists: /{MemberURI}
Those are different types of URIs that return different things when queried. I want to call them differently to document them individually.
Is there any way to do this?
Thanks!
EDIT:
The spec shows up just fine in Swagger-UI -- is this a bug in the editor or does the UI just ignore my error?
That's because the two paths can be identical. I understand that the parameters may uniquely identify them, but OpenAPI 2.0 (Swagger 2.0), 3.0 and 3.1 do not support full URI templates, and the path portion alone is inspected for uniqueness. So these:
/{foo}
/{bar}
are identical, even if foo must be a string, and bar must be a number. Please add your $0.02 on the OpenAPI Specification Repo as we're working on better path support right now.

Swagger equivalent path error even though paths are different [duplicate]

I'm trying to turn the Atom Publishing Protocol (RFC5023) in to a Swagger / OpenAPI spec to exercise writing those specs.
I ran into the following problem: in Atom there are different types of URIs, e.g. Collection and Member URIs.
My idea was to document it like this:
paths:
/{CollectionURI}:
get:
summary: List Collection Members
...
post:
summary: Create a Resource
...
parameters:
- $ref: "#/parameters/CollectionURI"
/{MemberURI}:
get:
summary: Retrieve a Resource
...
parameters:
- $ref: "#/parameters/MemberURI"
When I do that, swagger-editor claims that
Equivalent path already exists: /{MemberURI}
Those are different types of URIs that return different things when queried. I want to call them differently to document them individually.
Is there any way to do this?
Thanks!
EDIT:
The spec shows up just fine in Swagger-UI -- is this a bug in the editor or does the UI just ignore my error?
That's because the two paths can be identical. I understand that the parameters may uniquely identify them, but OpenAPI 2.0 (Swagger 2.0), 3.0 and 3.1 do not support full URI templates, and the path portion alone is inspected for uniqueness. So these:
/{foo}
/{bar}
are identical, even if foo must be a string, and bar must be a number. Please add your $0.02 on the OpenAPI Specification Repo as we're working on better path support right now.

Provide alternate (international) spelling for defined Swagger route

I'm working on an API spec in swagger that has an endpoint:
/authorizations
I would like to define an alternative spelling (authorisations) for this endpoint as well. Is this possible? Or do I need to define a separate route for each spelling?
/authorizations:
get:
description: Returns a list of authorizations
A possible workaround is to define another path that $refs the original path, this way you end up with two copies of the same path.
paths:
/authorizations:
get:
description: Returns a list of authorizations
responses:
200:
description: OK
/authorisations:
$ref: '#/paths/~1authorizations'
One limitation of this technique is that you cannot have operationId for these paths, because both paths will end up with the same ID, which is not allowed.
If you need to have different operationId in paths, you'll need to define the 2nd path in the usual way (i.e. copy-paste the definition from the 1st path).
Swagger currently does not support overloading/aliasing path definitions. I don't recall ever seeing such a request, but you're more than welcome on open an issue on https://github.com/wordnik/swagger-spec asking to add support for it in future versions.
See https://github.com/OAI/OpenAPI-Specification/issues/213 where one suggestion is to define a "renamed" path by using a 308 redirect:
/original-x:
description: Redirects to the new X
get:
responses:
'308':
description: This resource has been moved
headers:
Location:
schema:
type: string
default: /new-x
(I've not seen another means to implement this cleanly.)

Resources