eclipse-vertx / vertx-openapi

OpenAPI repository
Other
9 stars 6 forks source link

Additional Schema Files are always checked against the OpenAPI Schema #77

Closed Traderjoe95 closed 1 month ago

Traderjoe95 commented 1 month ago

Version

4.5.9

Context

I tried to split my OpenAPI document across multiple files by extracting some larger schema definitions to their separate files. To allow loading these files, I added them as additionalContractFiles in the call to OpenAPIContract.from. This fails because the additional files are validated against the full OpenAPI 3.1.0 specification, while they contain a simple JSON Schema.

In my opinion, the parser should offer the opportunity to reference arbitrary files, as long as the resulting schema is aligned with the OpenAPI specification.

Steps to reproduce

Here's a minimal schema to reproduce this:

openapi/openapi.yaml

openapi: 3.1.0
info:
  title: My Service
  version: 1.0.0
tags: []
paths:
  /v1/post:
    post:
      summary: Some POST request
      operationId: postBody
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RequestBody'
      responses:
        200:
          description: Success
        default:
          description: An unexpected error occurred
components:
  schemas:
    RequestBody:
      type: object
      properties:
        name:
          description: The unique name of the object
          $ref: 'schemas/Name.yaml'

openapi/schemas/Name.yaml

$schema: https://spec.openapis.org/oas/3.1/dialect/base
description: A case-insensitive string of 1-255 characters, serving as a name (unique identifier)
type: string
minLength: 1
maxLength: 255

Parsing the Contract

Map<String, String> additional = new HashMap<>();
additional.put("schemas/Name.yaml", "openapi/schemas/Name.yaml");

Future<OpenAPIContract> contract = OpenAPIContract.from(vertx, "openapi/openapi.yaml", additional).onFailure(t -> t.printStackTrace());

results in

Exception in thread "main" io.vertx.openapi.contract.OpenAPIContractException: The passed OpenAPI contract is invalid: Found issue in specification for reference: schemas/Name.yaml
    at io.vertx.openapi.contract.OpenAPIContractException.createInvalidContract(OpenAPIContractException.java:34)
    at io.vertx.openapi.contract.OpenAPIContract.lambda$null$4(OpenAPIContract.java:123)
    at io.vertx.core.impl.future.Mapping.onSuccess(Mapping.java:35)
    at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess$0(FutureBase.java:60)
    at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "maxLength" does not match unevaluated properties schema
    at [#/unevaluatedProperties].<#/maxLength>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "minLength" does not match unevaluated properties schema
    at [#/unevaluatedProperties].<#/minLength>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "type" does not match unevaluated properties schema
    at [#/unevaluatedProperties].<#/type>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "description" does not match unevaluated properties schema
    at [#/unevaluatedProperties].<#/description>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Property "$schema" does not match unevaluated properties schema
    at [#/unevaluatedProperties].<#/$schema>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/unevaluatedProperties)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "info"
    at [#/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "openapi"
    ... 1 more
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "webhooks"
    at [#/anyOf/2/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf/2/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "components"
    at [#/anyOf/1/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf/1/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not have required property "paths"
    at [#/anyOf/0/required].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf/0/required)
Caused by: io.vertx.json.schema.JsonSchemaValidationException: Instance does not match any subschemas
    at [#/anyOf].<#>(https://spec.openapis.org/oas/3.1/schema/2022-10-07#/anyOf)
CheesyBoy123 commented 1 month ago

Thanks @Traderjoe95 for this issue. I think it is related to https://github.com/eclipse-vertx/vertx-openapi/issues/16 which @pk-work did some work on. His branch 4_x_issue_16 had the changes. I'll check later today/this week if this solves your issue too (or feel free to checkout the branch yourself and test locally, it may just be out of date with the latest).

CheesyBoy123 commented 1 month ago

@Traderjoe95 I've rebased and made a few additional changes. I've created a unit test using your reproducer (1). It is passing now, but there is 1 thing with your spec that you may have to change:

From:

$ref: 'schemas/Name.yaml'

To:

$ref: 'https://schemas/Name.yaml'

and when creating the contract:

From:

Map<String, String> additional = new HashMap<>();
additional.put("schemas/Name.yaml", "name.yaml");

To:

Map<String, String> additional = new HashMap<>();
additional.put("https://schemas/Name.yaml", "name.yaml");

This is just a small quark in the underlying json schema. If no URL schema (https://) is provided a basic one (app:///) is prepended.

1) https://github.com/eclipse-vertx/vertx-openapi/pull/78/files#diff-855244058065bd13e92bd705f150195b0190150c844576a3d0e10062b1700766R165

CheesyBoy123 commented 1 month ago

Fixed in https://github.com/eclipse-vertx/vertx-openapi/pull/78