Skip to content

Message Identification when oneOf is expected #1095

Open

Description

@crazyash

I have an asyncapi, similar to the one below. Is there a standard way to identify the message that we receive in the channel?

For instance, In the below example, how to identify the message sent on test2 channel? How do we know if it's objectWithKey or objectWithKey2?

asyncapi: 3.0.0
info:
  title: OneOf example
  version: 1.0.0
channels:
  test:
    address: test
    messages:
      testMessages:
        $ref: '#/components/messages/testMessages'
  test2:
    address: test2
    messages:
      objectWithKey:
        payload:
          $ref: '#/components/schemas/objectWithKey'
      objectWithKey2:
        payload:
          $ref: '#/components/schemas/objectWithKey2'
operations:
  onTestMsg:
    action: receive
    channel:
      $ref: '#/channels/test'
    messages:
      - $ref: '#/channels/test/messages/testMessages'
  sendTest:
    action: send
    channel:
      $ref: '#/channels/test2'
    messages:
      - $ref: '#/channels/test2/messages/objectWithKey'
      - $ref: '#/channels/test2/messages/objectWithKey2'
components:
  messages:
    testMessages:
      payload:
        oneOf:
          - $ref: '#/components/schemas/objectWithKey'
          - $ref: '#/components/schemas/objectWithKey2'
    testMessage1:
      payload:
        $ref: '#/components/schemas/objectWithKey'
    testMessage2:
      payload:
        $ref: '#/components/schemas/objectWithKey2'
  schemas:
    objectWithKey:
      type: object
      properties:
        key:
          type: string
    objectWithKey2:
      type: object
      properties:
        key2:
          type: string

Activity

  1. github-actions commented on Mar 27, 2025

    @github-actions

    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.

  2. AnEngg commented on Apr 8, 2025

    @AnEngg
  3. kanchandeshmukh148 commented on Apr 8, 2025

    @kanchandeshmukh148
  4. github-actions commented on Aug 7, 2025

    @github-actions

    This issue has been automatically marked as stale because it has not had recent activity 😴

    It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

    There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

    Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

    Thank you for your patience ❤️

  5. ShreyasN707 commented on Nov 29, 2025

    @ShreyasN707

    @crazyash I'd like to work on this. Short proposal below (copy-paste ready):

    Problem:
    When a channel accepts multiple message shapes (oneOf), consumers cannot reliably tell which concrete message was received (e.g., objectWithKey vs objectWithKey2 on test2).

    Proposed solution (short):
    Add an explicit discriminator (a small type field) or use message headers so each concrete message can be identified reliably at runtime. Update schemas/messages to include a required type (or header) with a constant value and use oneOf/discriminator mapping for validation.

    Key steps:

    1. Add a type property to each concrete schema and make it required with a const value (e.g., type: "objectWithKey" / type: "objectWithKey2").

    2. Replace the loose oneOf with a oneOf plus a discriminator (or rely on the type field to disambiguate).

    3. Optionally, add the same type in message headers if your transport prefers header-based routing.

    4. Update consumer validation logic to inspect payload.type (or header) and route/validate accordingly.

    Minimal example (YAML snippet):

    components:
    schemas:
    objectWithKey:
    type: object
    required: [type, key]
    properties:
    type:
    type: string
    const: objectWithKey
    key:
    type: string

    objectWithKey2:
      type: object
      required: [type, key2]
      properties:
        type:
          type: string
          const: objectWithKey2
        key2:
          type: string
    

    messages:
    testMessages:
    payload:
    oneOf:
    - $ref: '#/components/schemas/objectWithKey'
    - $ref: '#/components/schemas/objectWithKey2'
    # Consumers can check payload.type to know which schema to use

    Acceptance criteria:

    • Every message includes a reliable identifier (payload.type or header).

    • Consumers can deterministically identify and validate incoming messages as objectWithKey or objectWithKey2.

    Risks / Notes:

    • If you cannot change payloads, use headers (transport-dependent) or detect by unique required properties (less robust).

    • Adding a discriminator is backward compatible if consumers tolerate the extra type field.

    Timeline:

    • I can implement schema/message updates and a short consumer validation example within one day.
  6. github-actions commented on Mar 30, 2026

    @github-actions

    This issue has been automatically marked as stale because it has not had recent activity 😴

    It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

    There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

    Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

    Thank you for your patience ❤️

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    stale❔ QuestionA question about the spec or processes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions