reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.69k stars 1.16k forks source link

Codegen - interface/type alias CreateUsingPostApiResponse already registered #2222

Closed dagi12 closed 1 week ago

dagi12 commented 2 years ago

Codegen is throwing error on duplicate operationIds. In my believe most of openApi spec files generated from controller method names has duplicates in operationIds. Simple controller method names often follow "get", "create", "update", "delete" convention.

Error: interface/type alias CreateUsingPostApiResponse already registered
    at registerInterface (/Users/erykmariankowski/programowanie/web/zamowienia4-client/node_modules/@rtk-query/codegen-openapi/src/generate.ts:95:13)
    at generateEndpoint (/Users/erykmariankowski/programowanie/web/zamowienia4-client/node_modules/@rtk-query/codegen-openapi/src/generate.ts:198:7)
    at /Users/erykmariankowski/programowanie/web/zamowienia4-client/node_modules/@rtk-query/codegen-openapi/src/generate.ts:118:15
    at Array.map (<anonymous>)
    at generateApi (/Users/erykmariankowski/programowanie/web/zamowienia4-client/node_modules/@rtk-query/codegen-openapi/src/generate.ts:117:34)
    at async generateEndpoints (/Users/erykmariankowski/programowanie/web/zamowienia4-client/node_modules/@rtk-query/codegen-openapi/src/index.ts:14:22)
    at async run (/Users/erykmariankowski/programowanie/web/zamowienia4-client/node_modules/@rtk-query/codegen-openapi/src/bin/cli.ts:64:7)
rambhual commented 2 years ago

I am also getting the same issue

aendel commented 2 years ago

It's happening the same to me, I don't know how to handle it

phryneas commented 2 years ago

Without a schema to reproduce it there isn't a lot we could say or do about this.

lostdev commented 1 year ago

Getting the same issue here. Most definitely caused by duplicate operation id's as well.

@phryneas : The following duplicate seems to be causing the issue for me; the same operation exists as both a POST and GET endpoint.

...
"/api/v1/details": {
      "get": {
        "tags": [
          "Details"
        ],
        "summary": "Retrieves detail records",
        "operationId": "Controller_Details",
        "consumes": [],
        "produces": [
          "application/json",
          "text/json"
        ],
        "parameters": [
          {
            "name": "filterKey",
            "in": "query",
            "description": "The filter key to apply.",
            "required": false,
            "type": "integer",
            "format": "int32"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/SDK.Models.v1.Detail"
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Details"
        ],
        "summary": "Retrieves detail records",
        "operationId": "Controller_Details",
        "consumes": [
          "application/json",
          "text/json"
        ],
        "produces": [
          "application/json",
          "text/json"
        ],
        "parameters": [
          {
            "name": "keywords",
            "in": "body",
            "description": "The keywords used when executing filters",
            "required": true,
            "schema": {
              "type": "object",
              "additionalProperties": {
                "type": "object"
              }
            }
          },
          {
            "name": "filterKey",
            "in": "query",
            "description": "The filter key to apply.",
            "required": false,
            "type": "integer",
            "format": "int32"
          }
        ],
...
Ledragon commented 1 year ago

Any workaround on this? Stumbled on this issue as well (two delete endpoints with different arguments)

vadimyen commented 9 months ago

I have the same problem

iliapnmrv commented 7 months ago

hey! any updates on this?

itbali commented 7 months ago

this is my api.json:

{
  "openapi": "3.0.3",
  "info": {
    "title": "cv-builder API",
    "description": "cv-builder API",
    "version": "0.1.7"
  },
  "tags": [
    {
      "name": "company",
      "description": "Company Information API"
    },
    {
      "name": "cv",
      "description": "API for managing candidate information with CRUD operations"
    },
    {
      "name": "pic",
      "description": "API for storing pictures (avatars from cv)"
    },
    {
      "name": "task",
      "description": "API for task management"
    },
    {
      "name": "attachment",
      "description": "API for receiving attachments"
    },
    {
      "name": "admin",
      "description": "API for administrators"
    }
  ],
  "servers": [
    {
      "url": "/api/v1"
    }
  ],
  "paths": {
    "/attachments/{attachmentId}": {
      "$ref": "./resources/attachment/attachment-by-id.json"
    },
    "/tasks": {
      "$ref": "./resources/task/tasks.json"
    },
    "/tasks/{taskId}": {
      "$ref": "./resources/task/task-by-id.json"
    },
    "/pic": {
      "$ref": "./resources/pic/pic.json"
    },
    "/pic/{picId}": {
      "$ref": "./resources/pic/pic-by-id.json"
    },
    "/cv": {
      "$ref": "./resources/cv/cv.json"
    },
    "/cv/{cvId}": {
      "$ref": "./resources/cv/cv-by-id.json"
    },
    "/companies": {
      "$ref": "./resources/company/companies.json"
    },
    "/companies/{companyId}": {
      "$ref": "./resources/company/company-by-id.json"
    },
    "/admin/tasks": {
      "$ref": "./resources/admin/tasks.json"
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ]
}

this is config file:

const config: ConfigFile = {
    schemaFile: "./cv-builder-api/api.json",
    apiFile: "./src/shared/api/api.ts",
    apiImport: "api",
    outputFile: "./src/shared/api/cvApi.ts",
    // outputFiles: {
    //  "./src/shared/api/adminApi.ts": {
    //      hooks: true,
    //      // filter with regExp all endpoints that not contain /admin
    //      filterEndpoints: [doesNotContainAdmin],
    //  },
    //  "./src/shared/api/cvApi.ts": {
    //      hooks: true,
    //      // filter with regExp all endpoints that contain admin
    //      filterEndpoints: [containsAdmin],
    //  },
    // },
    exportName: "cvApi",
    hooks: true,
    tag: true,
};

As you can see - i tried approach with moving endpoints with same ending into different files, but same error appeared.

npx @rtk-query/codegen-openapi openapi-config.ts                                                                                        
Error: interface/type alias GetTasksApiResponse already registered
itbali commented 7 months ago

found a solution for my case. Take a look at functions shouldContainAdmin I'm using it to filter endpoint with same argumentTypes to another file.

import { ConfigFile } from "@rtk-query/codegen-openapi";
import { OperationDefinition } from "@rtk-query/codegen-openapi/lib/types";

// this is function returning EndpointMatcherFunction that will be used to filter admin endpoints
const shouldContainAdmin = (withAdmin: boolean)=> (
    _operationName: string,
    operationDefinition: OperationDefinition
) => {
    return operationDefinition.path.includes("/admin/") === withAdmin;
}

const config: ConfigFile = {
    schemaFile: "./cv-builder-api/api.json",
    apiFile: "./src/shared/api/api.ts",
    apiImport: "api",
    outputFiles: {
        "./src/shared/api/adminApi.ts": {
            hooks: true,
            filterEndpoints: shouldContainAdmin(true),
        },
        "./src/shared/api/cvApi.ts": {
            hooks: true,
            filterEndpoints: shouldContainAdmin(false),
        },
    },
    exportName: "cvApi",
    hooks: true,
    tag: true,
};

export default config;

now i have two files created with same arguments so no conflicts any more...

markerikson commented 1 week ago

I'm going to close this because I'm not sure that there's anything we can do in the case where there's multiple definitions with the same name.