Skip to content

using "$ref": "#/responses/<name>" does not set request format #1547

@axel7083

Description

@axel7083

Might be related to #977

Description

When using a reference to a response definition, the format is not set to json in RequestParams. Leading to null result when using the generated api.

Example

Let's say you define your swagger with the following, (Example describe in documentation https://swagger.io/docs/specification/v2_0/describing-responses/#reusing-responses)

{
  "swagger": "2.0",
  "paths": {
    "/pet": {
      "get": {
        "operationId": "getPet",
        "produces": ["application/json"],
        "parameters": [],
        "responses": {
          "200": {
            "$ref": "#/responses/GetPetResponse"
          }
        }
      }
    }
  },
  "definitions": {
    "Pet": {
      "type": "object",
      "required": ["name"],
      "properties": {
        "id": {
          "type": "string"
        }
      }
    }
  },
  "responses": {
    "GetPetResponse": {
      "description": "successful operation",
      "schema": {
        "$ref": "#/definitions/Pet"
      }
    }
  },
}

Here is a comparison of the actual output vs the expected output.

Actual 🔴 Expected 🟢
getPet: (params: RequestParams = {}) =>
      this.request<PetTTT, any>({
        path: `/pet`,
        method: "GET",
        ...params,
      })
getPet: (params: RequestParams = {}) =>
      this.request<PetTTT, any>({
        path: `/pet`,
        method: "GET",
        format: "json", // <-- THIS
        ...params,
      })

Investigation

The format property seems to be conditionally defined here

<%~ responseFormatTmpl ? `format: ${responseFormatTmpl},` : '' %>

The responseFormatTmpl is calculated above

extractResponseBodyIfItNeeded = (routeInfo, responseBodyInfo, routeName) => {

Running in debugger mode and breaking on the following function while generating from the example above

const responseFormatTmpl = responseContentKind[responseBodyInfo.success && responseBodyInfo.success.schema && responseBodyInfo.success.schema.contentKind] || null;

Image

The responseBodyInfo seems to be computed in getResponseBodyInfo

const responseBodyInfo = this.getResponseBodyInfo(routeInfo, parsedSchemas);

The following line seems to be very problematic

const contentTypes = this.getContentTypes([requestInfo], operationId);

I don't understand why the operationId is passed to getContentTypes. Looking at the implementation of getContentTypes this is not intended to process strings.

Checking the only caller of getRequestInfoTypes we can see it already compute the contentTypes

const contentTypes = this.getContentTypes(responses, [
...(produces || []),
routeInfo["x-accepts"],

Therefore we should simply pass it down, and it fixes the problem

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions