Skip to content

path collision are adding prefix without checking the method #3428

@kossel

Description

@kossel

Description

When there is collision in paths, it will automatically append the prefix (code) however, it doesn't check if the methods collide too, sometimes different method might be in different spec:

input:

  • swagger1.json
{
  "swagger": "2.0",
  "info": {
    "version": "1.0.7",
    "title": "Swagger Petstore",
    "description": "Filtered spec containing only POST /pet/{petId}"
  },
  "host": "petstore.swagger.io",
  "basePath": "/v2",
  "schemes": ["https", "http"],
  "paths": {
    "/pet/{petId}": {
      "post": {
        "tags": ["pet"],
        "summary": "Updates a pet in the store with form data",
        "description": "",
        "operationId": "updatePetWithForm",
        "consumes": ["application/x-www-form-urlencoded"],
        "produces": ["application/json", "application/xml"],
        "parameters": [
          {
            "name": "petId",
            "in": "path",
            "description": "ID of pet that needs to be updated",
            "required": true,
            "type": "integer",
            "format": "int64"
          },
          {
            "name": "name",
            "in": "formData",
            "description": "Updated name of the pet",
            "required": false,
            "type": "string"
          },
          {
            "name": "status",
            "in": "formData",
            "description": "Updated status of the pet",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "405": {
            "description": "Invalid input"
          }
        },
        "security": [
          {
            "petstore_auth": ["write:pets", "read:pets"]
          }
        ]
      }
    }
  },
  "securityDefinitions": {
    "petstore_auth": {
      "type": "oauth2",
      "authorizationUrl": "https://petstore.swagger.io/oauth/authorize",
      "flow": "implicit",
      "scopes": {
        "read:pets": "read your pets",
        "write:pets": "modify pets in your account"
      }
    }
  }
}
  • swagger2.json
{
  "swagger": "2.0",
  "info": {
    "version": "1.0.7",
    "title": "Swagger Petstore",
    "description": "Filtered spec containing only GET and DELETE for /pet/{petId}"
  },
  "host": "petstore.swagger.io",
  "basePath": "/v2",
  "schemes": ["https", "http"],
  "paths": {
    "/pet/{petId}": {
      "delete": {
        "tags": ["pet"],
        "summary": "Deletes a pet",
        "description": "",
        "operationId": "deletePet",
        "produces": ["application/json", "application/xml"],
        "parameters": [
          {
            "name": "api_key",
            "in": "header",
            "required": false,
            "type": "string"
          },
          {
            "name": "petId",
            "in": "path",
            "description": "Pet id to delete",
            "required": true,
            "type": "integer",
            "format": "int64"
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid ID supplied"
          },
          "404": {
            "description": "Pet not found"
          }
        },
        "security": [
          {
            "petstore_auth": ["write:pets", "read:pets"]
          }
        ]
      }
    }
  },
  "securityDefinitions": {
    "api_key": {
      "type": "apiKey",
      "name": "api_key",
      "in": "header"
    },
    "petstore_auth": {
      "type": "oauth2",
      "authorizationUrl": "https://petstore.swagger.io/oauth/authorize",
      "flow": "implicit",
      "scopes": {
        "read:pets": "read your pets",
        "write:pets": "modify pets in your account"
      }
    }
  },
  "definitions": {
    "Category": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "name": {
          "type": "string"
        }
      }
    },
    "Pet": {
      "type": "object",
      "required": ["name", "photoUrls"],
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "category": {
          "$ref": "#/definitions/Category"
        },
        "name": {
          "type": "string",
          "example": "doggie"
        },
        "photoUrls": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "tags": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Tag"
          }
        },
        "status": {
          "type": "string",
          "enum": ["available", "pending", "sold"]
        }
      }
    },
    "Tag": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "name": {
          "type": "string"
        }
      }
    }
  }
}

The result I would expect after merging is something like this:

{
  "/api/userphotos": {
    "get": { /* from spec 1 */ },
    "patch": { /* from spec 1 */ },
    "delete": { /* from spec 1 */ },
    "post": { /* from spec 2 */ }
  }
}

However, the merged spec becomes:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.7",
    "title": "Swagger Petstore",
    "description": "Filtered spec containing only POST /pet/{petId}"
  },
  "paths": {
    "/pet/{petId}": {
      "post": {
        "tags": [
          "pet"
        ],
        "summary": "Updates a pet in the store with form data",
        "description": "",
        "operationId": "swagger1_updatePetWithForm",
        "consumes": [
          "application/x-www-form-urlencoded"
        ],
        "produces": [
          "application/json",
          "application/xml"
        ],
        "parameters": [
          {
            "name": "petId",
            "in": "path",
            "description": "ID of pet that needs to be updated",
            "required": true,
            "type": "integer",
            "format": "int64"
          },
          {
            "name": "name",
            "in": "formData",
            "description": "Updated name of the pet",
            "required": false,
            "type": "string"
          },
          {
            "name": "status",
            "in": "formData",
            "description": "Updated status of the pet",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "405": {
            "description": "Invalid input"
          }
        },
        "security": [
          {
            "petstore_auth": [
              "write:pets",
              "read:pets"
            ]
          }
        ],
        "requestBody": [
          {
            "name": "name",
            "in": "formData",
            "description": "Updated name of the pet",
            "required": false,
            "type": "string"
          },
          {
            "name": "status",
            "in": "formData",
            "description": "Updated status of the pet",
            "required": false,
            "type": "string"
          }
        ]
      }
    },
    "/swagger2/pet/{petId}": {
      "delete": {
        "tags": [
          "pet"
        ],
        "summary": "Deletes a pet",
        "description": "",
        "operationId": "swagger2_deletePet",
        "produces": [
          "application/json",
          "application/xml"
        ],
        "parameters": [
          {
            "name": "api_key",
            "in": "header",
            "required": false,
            "type": "string"
          },
          {
            "name": "petId",
            "in": "path",
            "description": "Pet id to delete",
            "required": true,
            "type": "integer",
            "format": "int64"
          }
        ],
        "responses": {
          "400": {
            "description": "Invalid ID supplied"
          },
          "404": {
            "description": "Pet not found"
          }
        },
        "security": [
          {
            "petstore_auth": [
              "write:pets",
              "read:pets"
            ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {},
    "parameters": {},
    "requestBodies": {},
    "responses": {},
    "headers": {},
    "securitySchemes": {},
    "examples": {},
    "links": {},
    "callbacks": {}
  }
}

and this generates the output


export const postPhotosV2ApiUserphotos = <...) => (options.client ?? client).post<...>({
    url: '/photosV2/api/userphotos',
    ...options,
    headers: {
        'Content-Type': 'application/json',
        ...options.headers
    }
});

Reproducible example or configuration

https://stackblitz.com/edit/hey-api-client-fetch-example-n41ipjsh?file=src%2Fclient%2Fsdk.gen.ts

Metadata

Metadata

Labels

bug 🔥Broken or incorrect behavior.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions