redocly-cli icon indicating copy to clipboard operation
redocly-cli copied to clipboard

Prevent relative references to document/schema objects from creating new top-level schema objects

Open Kerry-at-VIP opened this issue 4 years ago • 3 comments

Is your feature request related to a problem? Please describe.

Whenever I make a relative reference to either:

  • a sub-property of a schema object
  • directly to an inline object in the same or a different file

Then, when I run an openapi-cli build, it adds those referenced objects as new top level schema objects. This is cluttering up the schema view - potentially confusing for our consumer developers.

Describe the solution you'd like Some way to make references to objects in the document hierarchy, where after doing an openapi build, those references are maintained, rather than having them created as new top-level schema objects.

Describe alternatives tried I'm new at this, so I'm open to suggestions. I'm aware that it's entirely possible that I'm looking at this completely wrong.

Additional context As an example, let's say pre-build I have a top level schema Account.yaml:

type: object
required: [AccountNumber]
properties:
  AccountNumber:
    type: string
    description: blah blah blah

Then, in requestBodies folder I have Account-Validate.yaml:

required: true
content:
  application/json:
    schema:
      type: object
      required: [AccountNumber]
      properties:
        AccountNumber:
                $ref: ../schemas/Account.yaml#/properties/AccountNumber

So I'm making a relative reference to the AccountNumber property in the Account schema object. After building with openapi-cli, I see that there's a new top-level schema object:

components:
  schemas:
    AccountNumber:
      type: string
      description: The retail account ID number

Thoughts? Thanks!

Kerry-at-VIP avatar Jan 08 '21 20:01 Kerry-at-VIP

Describe alternatives tried I'm new at this, so I'm open to suggestions. I'm aware that it's entirely possible that I'm looking at this completely wrong.

I want to try to find some alternatives or help clarify this further.

The request body for Account-Validate is accepting an object, but it has the AccountNumber as the only property?

How do we determine what's not a valid schema to represent in schemas if it's used in the API?

Do you want, for example, schemas not of type object (e.g. string) to be dereferenced?

adamaltman avatar Jan 09 '21 16:01 adamaltman

Thanks for the response!

I'm working on an OAS3 spec for an older RPC-style api. The inputs for each api call are submitted as top-level json objects submitted through content, so every requestBody starts like this example:

required: true
content:
  application/json:
    schema:
      type: object
      required: [AccountNumber]
      properties:
        AccountNumber:
          $ref: '../schemas/Account.yaml#/properties/AccountNumber'

The Account.yaml schema has dozens of properties, but we'll focus on AccountNumber:

type: object
required: [ AccountNumber ]
properties:
  AccountNumber:
    type: string
    description: The retail account ID number

It seems to me that to keep the document DRY, every time an AccountNumber is called for in a request body, I should point it to the AccountNumber property of the top-level Account schema object like this: $ref: '../schemas/Account.yaml#/properties/AccountNumber'

That way, if we decided to modify the definition of the AccountNumber property, we only change it in one place, the Account schema object.

It seems to me that if a $ref is making a relative reference to a sub-property of a top-level schema object, that it would make more sense to maintain that reference, rather than creating a new duplicate of that as a new top-level schema object in the resulting build.

Unless I'm not looking at this correctly?

Kerry-at-VIP avatar Jan 10 '21 18:01 Kerry-at-VIP

@Kerry-at-VIP the purpose of bundle command is to get all parts (external references) of the definition into a single file. By default a new entry in components:schemas will be created for every external reference. This is done to keep the resulting definition DRY. You are also able to run bundle command with --dereferenced option. It will not create top-level schema objects in components:schemas but place them inline where they were referenced.

You can read more about bundle command here

slavikbez avatar Nov 08 '21 07:11 slavikbez

I think the dereferenced option covers most of the original request on this, and it's quite old so I'm closing but further issues are welcome if there's more that needs to be fixed/improved.

lornajane avatar Mar 31 '23 08:03 lornajane