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

OpenAPI 3.1.0 support: add rendering support for JSON Schema 2020-12 #8513

Closed
27 of 28 tasks
char0n opened this issue Mar 24, 2023 · 5 comments
Closed
27 of 28 tasks

OpenAPI 3.1.0 support: add rendering support for JSON Schema 2020-12 #8513

char0n opened this issue Mar 24, 2023 · 5 comments
Assignees
Labels
javascript Pull requests that update Javascript code type: feature version: 5.x

Comments

@char0n
Copy link
Member

char0n commented Mar 24, 2023

The goal of this issue is to add rendering support for JSON Schema 2020-12 within SwaggerUI. Currently there isn't any JSON Schema 2020-12 capable renderer.

There are multiple ways how JSON Schema 2020-12 can be represented depending on the use case. This issue will deal with an Object Representation. In this approach, the JSON Schema is represented as a JavaScript object that can be used in the React application. The goal of this object representation is to visualize the JSON Schema is such a way, that person look at this representation will easily understand what the JSON Schema does.

Implementation for the renderer should be done in separate SwaggerUI plugin where all JSON Schema 2020-12 related code will be concentrated. This will allow further to possibly decouple this code from SwaggerUI in future. We should not use SwaggerUI plugin system features (to allow future decupling), but rather classic React ones (like contexts).

Implementation phases

MVP1

This phase includes rendering Core vocabulary identifier keywords. This includes:

  • displaying properties keyword so that MVP1 have some value
  • creating recursive mechanism of rendering JSON Schema 2020-12
  • creating UI components
  • displaying schema type
  • displaying schema format
  • displaying schema description
  • displaying schema title
  • support for boolean schemas
  • basic collapsible behavior
  • extended collapsible behavior (expanding embedded schemas)
  • BooleanJSONSchema(false) should return never as type
  • infer type if type not defined
  • handling cycles while computing schema type
  • handling cycles during rendering
  • detect if schema is expandable
  • tracking embedding level
  • integrate MVP1 into Schemas section + lazy schema resolution
  • integrate deep linking into `Schemas section (not implemented for Draft 4 Schemas)
  • add support for defaultModelsExpandDepth config option

Current visual representation

image

MVP2

MVP3

MVP4

  • prepare code to use MVP3 in Operations
  • prepare code to use MVP3 in Webhooks
  • integrate MVP3 in Operations
  • integrate MPV3 in Callbacks
  • integrate MVP3 in Webhooks
  • include/exclude read-only properties from rendering
  • include/exclude write-only properties from rendering
@char0n char0n self-assigned this Mar 24, 2023
@char0n char0n added type: feature javascript Pull requests that update Javascript code version: 5.x labels Mar 24, 2023
@char0n
Copy link
Member Author

char0n commented Apr 10, 2023

Existing implementations

Here is the list of researched existing implementations.

atlassian json viewer

Supports JSON Schema Draft 07 only.

Repo: https://github.com/atlassian-labs/json-schema-viewer

image


asyncapi-react

Supports rendring JSON Schema Draft 04/05. To me personally, this looks like the most understandable representation.

Repo:

image


spotlight json-schema-viewer

Supports JSON Schema Draft 04/05.

Repo: https://github.com/stoplightio/json-schema-viewer

image

SwaggerUI

Supports JSON Schema Draft 04/05. UI is not the best on embedded (nested) schemas. Is intermingled with OpenAPI 3.0.x related features.

Repo: https://github.com/swagger-api/swagger-ui

image

@char0n
Copy link
Member Author

char0n commented Apr 10, 2023

Core vocabulary support

Identifiers

$schema

The $schema keyword is used to declare which JSON Schema draft version is being used for the schema definition. It provides important context about the schema, but it doesn't affect the validation or interpretation of the schema itself. Therefore, it's not necessary to render it in the visual representation of the schema, as it doesn't provide any additional information to the user.

However, it may be useful to display it in a text format for debugging or troubleshooting purposes. An example can be the case where $schema is defined, and is different from https://spec.openapis.org/oas/3.1/dialect/base - in that case we probably want to render some indication that we will process all schemas as if they would all have defined $schema=https://spec.openapis.org/oas/3.1/dialect/base.

$vocabulary

It could be useful to render the $vocabulary keyword in the JSON Schema 2020-12. The $vocabulary keyword allows us to specify a vocabulary to use for certain keywords and properties.

For example, if we are using the draft-07 vocabulary, we can use the minimum and maximum keywords to specify numeric ranges. However, if we are using the geographical-location vocabulary, we may use latitude and longitude instead.

Rendering the $vocabulary keyword could provide helpful context to understand which vocabulary is being used, and which keywords are available.

$id

The $id keyword is used to associate a URI with the schema, which can be used to reference the schema from other schemas or documents. By rendering this keyword, users can see the URI associated with the schema and understand how it is used in the larger context of the application or system.

The JSON Schema Draft 04 Renderer for SwaggerUI has a concept of name. $id field can be one of the data point that forms a name.

$anchor

While it may not have a significant effect on the overall rendering of the schema, it can be useful to include the $anchor value in the rendering for reference purposes.

The JSON Schema Draft 04 Renderer for SwaggerUI has a concept of name. $anchor field can be one of the data point that forms a name.

$dynamicAnchor

This keyword is currently not supported by ApiDOM, but we'll include this keyword into schema rendering.

$ref

For the MVP, it's best not to handle $ref rendering at all. As resolution and derferencing in JSON Schema 2020-12 is extremely complex, this renderer should only be concerned by rendering the schema into object representation. We can create an intercepting hook for $ref keyword, which will allow to dereference the $ref keyword before the result of dereferencing is rendered.

$dynamicRef

This keyword is currently not supported by ApiDOM, but we'll include this keyword into schema rendering.

$defs

It would make sense to render the $defs keyword if the schema is used in an OpenAPI 3.1.0 context. The $defs keyword is part of the JSON Schema specification and is used to define reusable schemas within a JSON Schema document. OpenAPI 3.1.0 uses JSON Schema as its schema language, and the Components Object in OpenAPI 3.1.0 is used to define reusable schemas, parameters, and responses. The Components Object can include $ref references to schemas defined in the $defs keyword, so it would be useful to render the $defs keyword in the visual representation of the JSON Schema in an OpenAPI 3.1.0 context.

$comment

We will render $comment keyword, as it might rely important information attached to the schema.

Applicators

Keywords for Applying Subschemas With Logic

allOf

Will be visually represented as All Of field.

anyOf

Will be visually represented as Any Of field.

oneOf

Will be visually represented as One Of field.

not

Will be visually represented as Not field.

Keywords for Applying Subschemas Conditionally

if

Will be visually represented as If field.

then

Will be visually represented as Then field.

else

Will be visually represented as Else field.

dependentSchemas

Will be visually represented in the same way as the properties field with name="Dependent schemas".

Keywords for Applying Subschemas to Arrays

prefixItems

Will be visually represented as Prefix items field.

items

Will be visually represented as Items field.

contains

Will be visually represented as Contains field.

Keywords for Applying Subschemas to Objects

properties

Properties are rendered as fields to the rendered representation.

patternProperties

Pattern properties are rendered as fields to the rendered representation with indication that the field is a patterned property.

additionalProperties

Can have form of boolean or object. For additionalProperties=true we're render label allowed. For additionalProperties=false we're render label forbidden.

propertyNames

Will be visually represented as Property names field.

A Vocabulary for Unevaluated Locations

unevaluatedItems

Will be visually represented as Unevaluated items field.

unevaluatedProperties

Will be visually represented as Unevaluated properties field.

@char0n
Copy link
Member Author

char0n commented Apr 10, 2023

Validation vocabulary support

Validation Keywords for Any Instance Type

type

This keyword is already part of MVP1, where it forms the source of truth for determining the schema type.

enum

Every item of the enum will be represented as string. stringify function from fn module will handle items conversion.

const

stringify function from fn module will handle converting value of const keyword into string.

Validation Keywords for Numeric Instances (number and integer)

multipleOf

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

maximum

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

exclusiveMaximum

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

minimum

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

exclusiveMinimum

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

Validation Keywords for Strings

maxLength

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

minLength

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

pattern

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

Validation Keywords for Arrays

maxItems

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

minItems

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

uniqueItems

Depending on this field the label of the constraint will either be items or unique items

maxContains

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

minContains

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

Validation Keywords for Objects

maxProperties

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

minProperties

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

required

Will be rendered as red star (*) next to the property name. Red start will be displayed only for properties that comes from properties keyword.

dependentRequired

For every property from properties keyword, compute the dependent required property names using fn.getDependentRequired and then pass these property names to JSONSchema component as dependentSchemas prop for rendering.

Vocabularies for Semantic Content With "format"

format

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

A Vocabulary for the Contents of String-Encoded Data

contentEncoding

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

contentMediaType

Will be rendered using Constraint component. fn will implement new function stringifyConstraints that transforms the keyword into a string.

contentSchema

Will be visually represented as Content schema field.

A Vocabulary for Basic Meta-Data Annotations

title

When JSONSchema component is rendered, it can accept optional name property. This name property is then passed to KeywordTitle component as title prop. KeywordTitle component renders the passed title prop or use fn.getTitle function to get the schema title.

description

KeywordDescription component is responsible for rendering the description keyword.

default

stringify function from fn module will handle converting value of const keyword into string.

deprecated

Will be rendered as red deprecated label before the type

readOnly

Will be rendered as gray read-only label, after the deprecated label.

writeOnly

Will be rendered as gray write-only label, after the read-only label.

char0n added a commit that referenced this issue Apr 14, 2023
char0n added a commit that referenced this issue Apr 19, 2023
char0n added a commit that referenced this issue May 12, 2023
…rds (#8660)

This change is related to JSON Schema 2020-12.

Refs #8513
char0n added a commit that referenced this issue May 16, 2023
char0n added a commit that referenced this issue May 16, 2023
As JSON Schema 2020-12 can be represented as
a Boolean Schema, different keyword detection
needs to be used.

Refs #8513
char0n added a commit that referenced this issue May 16, 2023
As JSON Schema 2020-12 can be represented as
a Boolean Schema, different keyword detection
needs to be used.

Refs #8513
@char0n
Copy link
Member Author

char0n commented May 17, 2023

@char0n char0n closed this as completed May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
javascript Pull requests that update Javascript code type: feature version: 5.x
Projects
None yet
Development

No branches or pull requests

1 participant