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

SwaggerEditor@next: Schema reference not found in OpenAPI 3.1.0 definition #4346

Closed
notaphplover opened this issue Aug 5, 2023 · 2 comments

Comments

@notaphplover
Copy link

Q&A (please complete the following information)

  • OS: Linux
  • Browser: chrome and firefox
  • Method of installation: dist assests? I just browsed https://editor-next.swagger.io/
  • Swagger-UI version: 5
  • Swagger/OpenAPI version: OpenAPI 3.1

Content & configuration

Simply browse https://editor-next.swagger.io/ and try the example OpenAPI definition (yes, I tried to simplify it as much as possible 😃)

Example Swagger/OpenAPI definition:

openapi: 3.1.0
info:
  title: One game API
  version: "1.0"
servers:
  - url: http://127.0.0.1:8000
    description: Local development server
components:
  schemas:
    EmailPasswordAuthCreateQueryV1:
      $id: https://onegame.schemas/api/v1/auth/email-password-auth-create-query.json
      title: EmailPasswordAuthCreateQueryV1
      type: object
      additionalProperties: false
      properties:
        email:
          type: string
        password:
          type: string
      required:
        - email
        - password
    CodeAuthCreateQueryV1:
      $id: https://onegame.schemas/api/v1/auth/code-auth-create-query.json
      title: CodeAuthCreateQueryV1
      type: object
      additionalProperties: false
      properties:
        code:
          type: string
      required:
        - code
    AuthV1:
      $id: https://onegame.schemas/api/v1/auth/auth.json
      title: AuthV1
      type: object
      additionalProperties: false
      properties:
        jwt:
          type: string
      required:
        - jwt
    AuthCreateQueryV1:
      $id: https://onegame.schemas/api/v1/auth/auth-create-query.json
      title: AuthCreateQueryV1
      anyOf:
        - $ref: "#/components/schemas/CodeAuthCreateQueryV1"
        - $ref: "#/components/schemas/EmailPasswordAuthCreateQueryV1"
paths:
  /v1/auth:
    post:
      summary: Create an authorization token
      operationId: createAuth
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AuthCreateQueryV1"
      responses:
        "200":
          description: Authorization token created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthV1"

Swagger-UI configuration options:
Default ones

Describe the bug you're encountering

Resolver error at requestBody.content.application/json.schema.$ref
Could not resolve reference: Evaluation failed on token: "components"
Resolver error at requestBody.content.application/json.schema.$ref
Could not resolve reference: Evaluation failed on token: "components"
Resolver error at requestBody.content.application/json.schema.anyOf.0.$ref
Could not resolve reference: Evaluation failed on token: "components"
Resolver error at requestBody.content.application/json.schema.anyOf.1.$ref
Could not resolve reference: Evaluation failed on token: "components"

To reproduce...

Steps to reproduce the behavior:

  1. Browse https://editor-next.swagger.io/
  2. Paste the example yaml.
  3. Click on the only endpoint provided to try it out
  4. An error should be displayed.

Expected behavior

I expect #/components/schemas/CodeAuthCreateQueryV1 and #/components/schemas/EmailPasswordAuthCreateQueryV1 to be resolved since it is defined.

Screenshots

Error screenshot
image

Additional context or thoughts

To be honest I don't know why this is happening. Other OpenAPI 3.1 viewers can resolve the reference correctly.

cc @char0n, I submit this issue after we were requested in swagger-api/swagger-ui#5891 to test the alpha, hope this helps.

@char0n
Copy link
Member

char0n commented Aug 5, 2023

Hi @notaphplover,

Unfortunately what you're seeing is a complexity (or rather a feature) that is inherited from OpenAPI 3.1.0 by using latest JSON Schema 2020-12. When you create references (using $ref keyword) within the context of the Schema Object the OpenAPI 3.1.0 tells us the following:

[Link]

Relative references in Schema Objects, including any that appear as $id values, use the nearest parent $id as a Base URI, as described by JSON Schema Specification Draft 2020-12. If no parent schema contains an $id, then the Base URI MUST be determined according to RFC3986.

It's also explained in more layman's terms here: https://json-schema.org/understanding-json-schema/structuring.html#id13


Now let's analyze your definition, and find out why it fails to resolve:

Main issue is in following Schema Object

AuthCreateQueryV1:
      $id: https://onegame.schemas/api/v1/auth/auth-create-query.json
      title: AuthCreateQueryV1
      anyOf:
        - $ref: "#/components/schemas/CodeAuthCreateQueryV1"
        - $ref: "#/components/schemas/EmailPasswordAuthCreateQueryV1"

When resolver sees the $ref: "#/components/schemas/CodeAuthCreateQueryV1", it needs to estabilish the baseURI for it. Here is the sequence of steps how this happens:

  1. Closes parent $id keyword containing https://onegame.schemas/api/v1/auth/auth-create-query.json is resolved against retrievalURI, which is https://editor-next.swagger.io/, resulting in https://onegame.schemas/api/v1/auth/auth-create-query.json (baseURI)
  2. $ref keyword containing "#/components/schemas/CodeAuthCreateQueryV1" is resolved against closest baseURI form of $id keyword which results in https://onegame.schemas/api/v1/auth/auth-create-query.json#/components/schemas/CodeAuthCreateQueryV1. Obviously no-schema can be found at that location so the resolution produces error.
  3. the same process repeats for $ref keyword containing "#/components/schemas/EmailPasswordAuthCreateQueryV1"

Now that we know why it fails, how do we fix it? Because you're using $id keywords in your Schema Objects, you now have to construct canonical URIs from them, in order to reference them. Here is the corrected version of your definition:

openapi: 3.1.0
info:
  title: One game API
  version: "1.0"
servers:
  - url: http://127.0.0.1:8000
    description: Local development server
components:
  schemas:
    EmailPasswordAuthCreateQueryV1:
      $id: https://onegame.schemas/api/v1/auth/email-password-auth-create-query.json
      title: EmailPasswordAuthCreateQueryV1
      type: object
      additionalProperties: false
      properties:
        email:
          type: string
        password:
          type: string
      required:
        - email
        - password
    CodeAuthCreateQueryV1:
      $id: https://onegame.schemas/api/v1/auth/code-auth-create-query.json
      title: CodeAuthCreateQueryV1
      type: object
      additionalProperties: false
      properties:
        code:
          type: string
      required:
        - code
    AuthV1:
      $id: https://onegame.schemas/api/v1/auth/auth.json
      title: AuthV1
      type: object
      additionalProperties: false
      properties:
        jwt:
          type: string
      required:
        - jwt
    AuthCreateQueryV1:
      $id: https://onegame.schemas/api/v1/auth/auth-create-query.json
      title: AuthCreateQueryV1
      anyOf:
        - $ref: https://onegame.schemas/api/v1/auth/code-auth-create-query.json
        - $ref: https://onegame.schemas/api/v1/auth/email-password-auth-create-query.json
paths:
  /v1/auth:
    post:
      summary: Create an authorization token
      operationId: createAuth
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AuthCreateQueryV1"
      responses:
        "200":
          description: Authorization token created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthV1"

To be honest I don't know why this is happening.

Hopefully I did explain clearly why this is happening. Using JSON Schema 2020-12 inside OpenAPI 3.1.0 can become complex, and understanding all this rules of resolution IMHO is impractical for JSON Schema 2020-12 users. But, it's what it is and we implement the rules of resolution as precise as we can, given the specification.

Other OpenAPI 3.1 viewers can resolve the reference correctly.

Can you enumerate which ones? Are you sure they implement proper rules of resolution compliant with the OpenAPI 3.1.0 and JSON Schema 2020-12 spec?

Hope this comment helped you a bit.

Refs asyncapi/spec-json-schemas#298 (comment)

@char0n char0n closed this as completed Aug 5, 2023
@notaphplover
Copy link
Author

notaphplover commented Aug 6, 2023

Hey @char0n, thank you so much for the detailed explanation! It's been very instructive.

Can you enumerate which ones? Are you sure they implement proper rules of resolution compliant with the OpenAPI 3.1.0 and JSON Schema 2020-12 spec?

I've been trying ReDoc and RapiDoc these days, I'm sure the ReDoc one resolves the reference, but what should matter is what the spec says and I completelly overlooked it.

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