Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAS extension supporting external documentation references #85

Open
cmars opened this issue Dec 2, 2021 · 5 comments
Open

OAS extension supporting external documentation references #85

cmars opened this issue Dec 2, 2021 · 5 comments

Comments

@cmars
Copy link
Contributor

cmars commented Dec 2, 2021

Add support for including free-form markdown in API documentation.

We want the compiled OpenAPI spec to provide everything needed to generate API documentation. However, we also don't want to have to author this content in a large JSON string with escaped newlines in an actual OpenAPI spec.

Instead, what we want is the ability to reference standalone markdown files, so that they are included in the compiled OpenAPI spec (possibly as large JSON strings), which may then be processed by an API documentation SPA or site generator.

So, I'm proposing an extension, x-snyk-doc-content. An example:

x-snyk-doc-content:
  intent: header
  format: markdown
  $ref: "/path/to/header.md"

What these properties mean:

  • intent is a hint to the processor of the extension indicating where to put the rendered content. This might be an element #id, a RapiDoc slot name, or something else.
  • format indicates how to parse and process the content. Defaults to "markdown" if not specified. Again, this is just a hint to the processor of the extension.
  • $ref works how you'd expect it to, it's a path or URL containing the content to be included.

As an alternative to $ref:, contents: contains the literal documentation contents inline as a string. In YAML, this can be expressed with a multiline string, contents: |- for example. In JSON, well, it's a large newline-escaped monster of a quoted string.

When Vervet localizes an OpenAPI spec, it should replace the $ref: properties with contents: in this extension. This will require some custom implementation, as the core kin-openapi doesn't do this for us with made-up extensions. However, it is possible -- see the implementation of vervet.IncludeHeaders for an example of resolving custom extension $refs.

@jcsackett
Copy link
Contributor

jcsackett commented Dec 2, 2021

Can extension fields be added to any part of the schema? Because if so target seems unnecessary--better to have the ref with the associated part of the schema and whatever processor decides from there.

If not, I think target ought to be more specific to something within the rest of the openapi spec--it seems peculiar to include a target hint for e.g. RapiDoc slots, since that's an implementation detail someone updating docs in the app shouldn't need to know/think about.

Otherwise I really dig this idea.

@cmars
Copy link
Contributor Author

cmars commented Dec 2, 2021

If we make the extension purely contextual and remove target: -- so that it applies to its parent element -- is it expressive enough to allow for including content that goes into a page header, extra sidebar sections, etc.? All of these things might go in the top-level of the OpenAPI spec, but how does the docs processor then know where to place the content?

Maybe the answer is that we use both; we use target: (is there now a more apt name for this?) as an abstract locator or hint that can be used by the docs processor to decide where to put things, and use the extension parent to determine the scope? So in that case, target: doesn't map 1:1 with RapiDoc tags, but tells a docs processor "this is what this chunk of content is intended to be used for" and the processor decides where to place it in the context of where it occurs in the OpenAPI doc.

@jcsackett
Copy link
Contributor

Maybe the answer is that we use both; we use target: (is there now a more apt name for this?) as an abstract locator or hint that can be used by the docs processor to decide where to put things, and use the extension parent to determine the scope? So in that case, target: doesn't map 1:1 with RapiDoc tags, but tells a docs processor "this is what this chunk of content is intended to be used for" and the processor decides where to place it in the context of where it occurs in the OpenAPI doc.

Ok, this seems like a reasonable field then, and I think you already named it when you said what it would be for: intent. Sound good?

@cmars
Copy link
Contributor Author

cmars commented Dec 2, 2021

One thing we should also make clear is when to use this extension, vs. existing features in OpenAPI. In some cases, a description: might be enough. This should be used sparingly, when it is not enough.

@cmars
Copy link
Contributor Author

cmars commented Dec 6, 2021

This can be a linting rule; only allow use of the extension if a non-empty description is provided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants