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

Discriminator support to be aligned with OAS3 #1073

Open
francocm opened this issue Oct 16, 2024 · 1 comment
Open

Discriminator support to be aligned with OAS3 #1073

francocm opened this issue Oct 16, 2024 · 1 comment
Labels
💡 Proposal (RFC 1) RFC Stage 1 (See CONTRIBUTING.md)

Comments

@francocm
Copy link

Context

The overlap in specification between AsyncAPI and OpenAPI specs allows the combining of common models across both.

Example:

./models/foo.yaml
openapi: 3.1.0
info:
  title: foo-models
  description: Models for Foo
  contact:
    name: Foo Team
  version: 1.0.0
paths: { }
components:
  schemas:
    Foo:
      type: object
      properties:
        id:
          type: string
./apis/foo.openapi.ayml
openapi: "3.1.0"
info:
  title: "foo"
  description: "API Specifications for `foo`."
  version: "1.0.0"
servers:
  - url: http://localhost:8080/
    description: Local Dev
paths:
  /foo:
    get:
      summary: "Get Foos"
      description: "Get Foos"
      operationId: "getFoos"
      responses:
        "200":
          description: "OK"
          content:
            'application/json':
              schema:
                type: array
                items:
                  $ref: "../models/foo.yaml#/components/schemas/Foo"
./events/foo.asyncapi.ayml
asyncapi: 3.0.0
info:
  title: foo Events
  version: 1.0.0
servers:
  foo-local:
    host: localhost:1234
    protocol: foo
    description: Foo broker (local dev)
    security:
      - $ref: '#/components/securitySchemes/plainSecurity'
defaultContentType: application/json
channels:
  FooEvents:
    address: foo.events
    description: The topic on which foo events are published on.
    messages:
      fooQueriedEvent:
        $ref: '#/components/messages/fooQueriedEvent'
operations:
  'foo.queried':
    action: send
    channel:
      $ref: '#/channels/FooEvents'
    messages:
      - $ref: '#/channels/FooEvents/messages/fooQueriedEvent'
components:
  messages:
    fooQueriedEvent:
      name: fooQueriedEvent
      title: Foo Queried Event
      summary: Foo Queried Event
      description: Foo Queried Event
      contentType: application/json
      payload:
        $ref: '../models/foo.yaml#/components/schemas/Foo'
  securitySchemes:
    plainSecurity:
      type: plain
      description: Plain unauthenticated connection

Problem

It's quite evident that AsyncAPI in general has no compatibility issues with OpenAPI specifications.

However, the problem lies with the use of discriminator in a oneOf situation.

If I update ./models/foo.yaml to this:

openapi: 3.1.0
info:
  title: foo-models
  description: Models for Foo
  contact:
    name: Foo Team
  version: 1.0.0
paths: { }
components:
  schemas:
    Foo:
      type: object
      properties:
        id:
          type: string
        bazAttributes:
          $ref: '#/components/schemas/OneOfBazAttributes'
    OneOfBazAttributes:
      type: object
      properties:
        type:
          type: string
          enum: [ 'RealBaz', 'MockBaz' ]
      discriminator:
        propertyName: type
        mapping:
          RealBaz: '#/components/schemas/RealBazAttributes'
          MockBaz: '#/components/schemas/MockBazAttributes'
    RealBazAttributes:
      allOf:
        - $ref: '#/components/schemas/OneOfBazAttributes'
      type: object
      properties:
        bazId:
          type: string
    MockBazAttributes:
      allOf:
        - $ref: '#/components/schemas/OneOfBazAttributes'
      type: object
      properties:
        xyzId:
          type: string
Output Result
OpenAPI Works as expected
AsyncAPI Fails with "discriminator" property type must be string channels.FooEvents.messages.fooQueriedEvent.payload.properties.bazAttributes.discriminator

This is using the official asyncapi CLI binary provided by asyncapi/cli:2.6.0 docker image, but also any other AsyncAPI tool I could find.

Root Cause

From what I can understand, AsyncAPI implements discriminator using the schema that OpenAPI 2.x (Swagger) had, i.e.:

OneOfBazAttributes:
  type: object
  properties:
    type: 
      type: string
      enum: [ 'RealBazAttributes', 'MockBazAttributes' ]
  discriminator: type
# with the expectation of having the value of `type` matching
# the object name exactly as defined in the YAML

(although the AsyncAPI render does not render any oneOf options, but all validations now pass successfully).

OpenAPI moved to a newer schema in 3.x, and whilst AsyncAPI does not seem to have problems with the OpenAPI 3.x schema compatibility, the specific discriminator capability seems to still be stuck in the 2.x world.

As it is, I do not see any clean way to be able to support discriminator and both OpenAPI and AsyncAPI simultaneously, without fixing this issue, or rolling everything back to 2.x.

Proposal

Align the AsyncAPI spec around discriminator to that of OpenAPI 3.1.x, and release it as AsyncAPI 3.1.0.


Keen to see your thoughts.

Thanks anyone participating.

@francocm francocm added the 💡 Proposal (RFC 1) RFC Stage 1 (See CONTRIBUTING.md) label Oct 16, 2024
Copy link

Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our contributors guide and the instructions about a basic recommended setup useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💡 Proposal (RFC 1) RFC Stage 1 (See CONTRIBUTING.md)
Projects
None yet
Development

No branches or pull requests

1 participant