stoplightio / spectral

A flexible JSON/YAML linter for creating automated style guides, with baked in support for OpenAPI (v3.1, v3.0, and v2.0), Arazzo v1.0, as well as AsyncAPI v2.x.
https://stoplight.io/spectral
Apache License 2.0
2.51k stars 240 forks source link

Preserve `$ref` when resolving references #2390

Closed ctreatma closed 1 year ago

ctreatma commented 1 year ago

User story. As a spectral user, I can identify which objects are $refs, so that I can ensure that complex objects are appropriately named.

Is your feature request related to a problem?

We generate client code from our OpenAPI specification; sometimes, the structure of our spec causes the generators to produce suboptimal code.

For example, an API endpoint might define a request body schema like this:

post:
  operationId: createThingy
  #...
  responses:
    "200":
      content:
        application/json:
          schema:
            oneOf:
            - $ref: '../../../components/schemas/OriginalThingyInput.yaml'
            - $ref: '../../../components/schemas/NewThingyInput.yaml'

That is valid, but a code generator will look at that and generate a model called CreateThingy200Response.

Thus far, we haven't found a way to detect, using spectral, whether the oneOf is inline or if it came from a resolved $ref.

Describe the solution you'd like

We would like an option that can be specified to resolve references and maintain the $ref property so that we can tell where the $refs were after resolution.

Additional context Add any other context or screenshots about the feature request here.

P0lip commented 1 year ago

Have you tried using resolved on a rule?

ctreatma commented 1 year ago

I tried using resolved: false, and it looks like it disables all reference resolution, so we only get the content of the root document. Our paths are referenced roughly like this:

paths:
  /my/path:
    $ref: paths/mypath.yaml

so the schema chunk in the issue description is unreachable with resolved: false, and with resolution enabled, we have no record that there was a ref in the first place.

P0lip commented 1 year ago

A custom function has an access to an unresolved document, so you could try accessing that if you haven't done it yet

mnaumanali94 commented 1 year ago

@ctreatma Does that work for you?

ctreatma commented 1 year ago

It sounds promising but I haven't had enough time to really dig into it. I started looking through the unresolved document data for my spec but having some trouble figuring out how to go from a path in the resolved document to corresponding path in the correct unresolved document.

P0lip commented 1 year ago

I'll close the ticket in the meantime. Feel free to follow up here in case you ran into the issue :)