78

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

Helen
  • 87,344
  • 17
  • 243
  • 314
Tommy
  • 12,588
  • 14
  • 59
  • 110

2 Answers2

76

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
Helen
  • 87,344
  • 17
  • 243
  • 314
  • 2
    Is Swagger on OpenAPI 3? – Tommy Jan 25 '18 at 16:51
  • @Tommy: "Swagger" is a collective name for many projects - Swagger Editor, Swagger UI, etc. Which project do you mean? – Helen Jan 25 '18 at 17:12
  • 1
    it appears "swagger specification" has been renamed "open api specification" according to this, I didn't know that, thanks: https://swagger.io/specification/ – Tommy Jan 25 '18 at 18:42
  • @Helen I have implemented the above into Swagger, but I am not seeing any response in the documentation. Surely if you specify two possible responses, it will show them both in the docs? Otherwise, what's the point in the feature or am I missing something? – Ben Carey Dec 16 '18 at 20:07
  • @BenCarey It's a [known issue](https://github.com/swagger-api/swagger-ui/issues/3803) (or rather unimplemented feature) in Swagger UI. I updated the answer and added a workaround. – Helen Dec 17 '18 at 10:51
  • @Helen - thank you for your prompt response. Am I correct in thinking that there is also an issue with specifying 'Multiple Examples'? In short, I am looking to document multiple example responses for the same HTTP code on one request. I have done my research and it appears that this may be possible, but it is not yet reflected in the UI... – Ben Carey Dec 17 '18 at 10:54
  • I can't make it work. Can you kindly be more specific and replace `- $ref: '#/components/schemas/ResponseOne'` by `type` definitions? Thanks – João Pimentel Ferreira Dec 18 '22 at 15:39
-7

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.

CristianTM
  • 330
  • 2
  • 8
  • 6
    This is not a valid spec - query parameters are not allowed in paths, they must be defined under `parameters`. There are existing proposals to allow query strings in paths: [Proposal: Querystring in Path Specification](https://github.com/OAI/OpenAPI-Specification/issues/164), [Accommodate legacy APIs by allowing query parameters in the path](https://github.com/OAI/OpenAPI-Specification/issues/123) – Helen Jan 25 '18 at 17:17