openapi-generator: Duplicate classes / Models are generated if ( $ref) referenced externally.

Description

If Schemas are referenced in cyclic manner, the Models are generated twice. In below code,the Model ProblemDetails is generated twice as

  • ProblemDetails.java
  • ProblemDetails2.java

Is the correct way to reference? If Not why? and How to fix the above case?

openapi-generator version

openapi-generator-cli-4.0.0-beta3

OpenAPI declaration file content or url

openapi.yaml

openapi: 3.0.0
info:
  title: Common Data Types
  version: "1.0"
paths:
  /{appId}/subscriptions:
    get:
      summary: read all of the active subscriptions for the app.
      operationId: getSubscriptionsById
      parameters:
        - name: appId
          in: path
          description: App ID
          required: true
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: OK (Successful)
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subscription'
        '500':
          $ref: './common.yaml#/components/responses/E500'  
components:
  schemas:
      ProblemDetails:
        type: object
        properties:
          title:
            type: string
            description: A short, human-readable summary of the problem
          status:
            type: integer
            description: The HTTP status code for this occurrence of the problem.
      Subscription:
        type: string

common.yaml

openapi: 3.0.0
info:
  title: Common Data Types
  version: "1.0"
paths: {}
components:
  responses:
    E500:
      description: Server Error
      content:
        application/json:
          schema:
            $ref: './openapi.yaml#/components/schemas/ProblemDetails'
Command line used for generation

java -jar openapi-generator-cli-4.0.0-beta3.jar generate -i openapi.yaml -g spring -o ./temp

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 17
  • Comments: 40 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Hi all, For example insted of: ‘./common.yaml#/components/responses/E500’ write ‘./common.yaml/#/components/responses/E500’

After this modification I was able to remove duplicity 😉

After playing around with external refs for a bit I discovered that swagger-parser will do some normalization on them, but it seems to happen lazily.

If you have a ref like

somefile.yml#/components/schemas/SomeSchema

then it will become

./somefile.yml#/components/schemas/SomeSchema

inside the parser after the first time this ref is resolved. Internally SomeSchema is cached when it is first read, when accessed the second time its source is different (somefile.yml != ./somefile.yml) so a number is appended to its name to avoid conflicts.

Prefixing relative paths with ./ solves this problem, but it seems the parser still has problems normalizing the paths relative to the root spec file as having complex relative references (e.g. different levels, from different subdirectories) still break the parser.

Same problem here. Duplicated classes get generated once another yaml $ref another yaml’s component. A bit sad not seeing any oficial workaround regarding this issue since it has been reported a while ago.

Bumping this. Same issue in typescript generator as well.

Has been fixed in https://github.com/swagger-api/swagger-parser/pull/1566, no duplicate classes are generated anymore when using version 2.0.26.

Good news, the issue is resolved in the Swagger-Parser (https://github.com/swagger-api/swagger-parser/issues/1081#issuecomment-607169681, https://github.com/swagger-api/swagger-parser/issues/1292). We must only wait for the next release, to use it in the generator

https://github.com/OpenAPITools/openapi-generator/issues/2701#issuecomment-582320928 Thank you for your analysis. I was able to resolve it. I prefixed each path in $ref with ./ and duplicate classes are gone.

.

When we fixed this locally in a fork, the fix looked like this:


if (existingModel != null) {
--
  | LOGGER.debug("A model for " + existingModel + " already exists");
  |  
  | /*
  | * Added an additional check here - schema.get$ref() != null to ensure we generate
  | * a single model file for a single model schema.
  | */
  | if(existingModel.get$ref() != null \|\| schema.get$ref() != null) {
  | // use the new model
  | existingModel = null;
  | }else{
  | //We add a number at the end of the definition name
  | int i = 2;
  | for (String name : schemas.keySet()) {
  | if (name.equals(possiblyConflictingDefinitionName)) {
  | tryName = possiblyConflictingDefinitionName + "_" + i;
  | existingModel = schemas.get(tryName);
  | i++;
  | }
  | }
  | }
  | }


That’s not quite what the latest commit to ExternalRefProcessor in your github is doing.

waiting for a feedback from swagger-parser team.