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

A mechanism to intercept and modify `$ref` before resolution

Open shabbyrobe opened this issue 4 years ago • 1 comments

Is your feature request related to a problem? Please describe. I'm trying to intercept and rewrite $ref links as part of a complex bundling workflow involving a library of shared multi-file JSON schema components and several OpenAPI specs (and other non-OpenAPI schemas) that depend on them. The shared schema components have their own bundling processes and workflows that I have some, but not a lot, of influence over.

It's easy enough when referencing the shared schemas from OpenAPI as I can just use a relative filesystem path, but when they refer to each other it's trickier as I have less control and can't really change the id and referencing scheme in those components.

The build infrastructure and schema resources for this project are private and heavily constrained, so they can't easily be deployed, which means the URLs we are using aren't able to be resolved. This is arguably the biggest smell here but it's the hand I've been dealt and I need to play it, sadly.

For instance:

openapi.yml:

lotsOfParentContext:
  $ref: "../../shared/thing.json"

Shared schema thing.json, I can't really change this much:

{
  "type": "object",
  "properties": {
    "other": {
      "//": "the following URL won't ever resolve to the actual schema, it's used more as a fully qualified namespace identifier",
      "$ref": "https://example.com/shared/other.json"
    }
  }
}

Shared schema other.json, in the same folder as thing.json:

{"type": "object"}

I had hoped to be able to translate things like fully qualified URLs to local file system paths, for instance:

From: {"$ref": "https://example.com/path/to/standalone/schema.json"}
To:   {"$ref": "/absolute/local/file/path/to/standalone/schema.json"}

Unfortunately I haven't yet found a way to do this (or something like it).

Describe alternatives you've considered I tried to implement this using a preprocessor, but preprocessing seems to happen after $ref resolution. I also tried poking around with the resolve config but that seems more limited to tweaking headers for resolving external URL $refs.

Describe the solution you'd like Maybe something added to plugins that allows the ref resolving step to be intercepted? Or possibly something added to the resolve config section to allow a regex and replacement pattern with backreferences? I'm not particularly fussed, nor familiar enough with the existing code, to have a strong opinion on the actual solution.

Additional context Happy to provide any further details if this request is unclear. Perhaps this is already possible and I'm just missing something.

shabbyrobe avatar Nov 23 '21 04:11 shabbyrobe

Have you tried the dereferenced (-d) flag yet on the bundle command? https://redoc.ly/docs/cli/commands/bundle/

Edit: this won't work if the URLs can't be resolved. I misread this and thought you wanted to pull from FQ URLs and move that to the local FS. Instead, you want to bypass that and use what is already on the local FS?

(In other words, ignore my comment... this is indeed a feature request.)

adamaltman avatar Dec 01 '21 20:12 adamaltman

Thanks for making this suggestion, but the functionality requested here is outside the scope of the tool, so I'm closing this old request. Please don't hesitate to keep making more suggestions for us though :)

lornajane avatar Apr 03 '23 07:04 lornajane