-
-
Notifications
You must be signed in to change notification settings - Fork 336
Description
We’re trying to model polymorphic objects in a list using AsyncAPI 3.0.0 and JSON Schema (Draft 7), with class generation via Modelina. However, it’s unclear what the recommended or correct way is to define inheritance in this context — especially for arrays of polymorphic types.
The Goal ✅
Will be using an example:
Define a schema where an array of items (workers) can contain different subtypes (Employer, Employee) inheriting from a base type (Worker), and ensure correct support in tools like Modelina for code generation.
What we've tried (simplified versions below) 🔍
Option 1 – use of allOf on subclasses
Subtypes extend Worker, workers just refers to Worker.
asyncapi: 3.0.0
.....
components:
schemas:
WorkersCreatedEvent:
title: WorkersCreatedEvent
type: object
properties:
id:
type: string
format: uuid
workers:
type: array
items:
$ref: '#/components/schemas/Worker'
required:
- id
Worker:
type: object
properties:
name:
type: string
discriminator: "@type"
Employer:
title: Employer
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
hasFullAccess:
type: boolean
required:
- hasFullAccess
Employee:
title: Employee
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
registrationDate:
type: string
required:
- registrationDate
Option 2 – allOf on subclasses + anyOf and allOf on array items
Array items use anyOf to allow multiple subtypes explicitly but also mark it they should be all of type worker
asyncapi: 3.0.0
....
components:
schemas:
WorkersCreatedEvent:
title: WorkersCreatedEvent
type: object
properties:
id:
type: string
format: uuid
workers:
type: array
items:
title: WorkerMixin
allOf:
- $ref: '#/components/schemas/Worker'
anyOf:
- $ref: '#/components/schemas/Employer'
- $ref: '#/components/schemas/Employee'
Worker:
title: Worker
type: object
properties:
name:
type: string
discriminator: "@type"
Employer:
title: Employer
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
hasFullAccess:
type: boolean
required:
- hasFullAccess
Employee:
title: Employee
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
registrationDate:
type: string
required:
- registrationDate
Option 3 – oneOf declared in base class
Worker uses oneOf to point to valid subtypes directly.
asyncapi: 3.0.0
....
components:
schemas:
WorkersCreatedEvent:
title: WorkersCreatedEvent
type: object
properties:
id:
type: string
format: uuid
workers:
type: array
items:
$ref: '#/components/schemas/Worker'
Worker:
type: object
properties:
name:
type: string
discriminator: "@type"
oneOf:
- $ref: '#/components/schemas/Employer'
- $ref: '#/components/schemas/Employee'
Employer:
title: Employer
type: object
allOf:
- type: object
properties:
hasFullAccess:
type: boolean
required:
- hasFullAccess
Employee:
title: Employee
type: object
allOf:
- type: object
properties:
registrationDate:
type: string
required:
- registrationDate
Option 4 – allOf on subclasses + anyOf on array
No inheritance on base class, just union the subtypes directly in the array definition.
asyncapi: 3.0.0
....
components:
schemas:
WorkersCreatedEvent:
title: WorkersCreatedEvent
type: object
properties:
id:
type: string
format: uuid
workers:
type: array
items:
title: WorkerItems
anyOf:
- $ref: '#/components/schemas/Employer'
- $ref: '#/components/schemas/Employee'
Worker:
type: object
properties:
name:
type: string # No properties cause Worker not be generated
discriminator: "@type"
Employer:
title: Employer
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
hasFullAccess:
type: boolean
required:
- hasFullAccess
Employee:
title: Employee
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
registrationDate:
type: string
required:
- registrationDate
Option 5 – allOf on subclasses + oneOf on array
asyncapi: 3.0.0
...
components:
schemas:
WorkersCreatedEvent:
title: WorkersCreatedEvent
type: object
properties:
id:
type: string
format: uuid
workers:
type: array
items:
title: WorkerMixin
oneOf:
- $ref: '#/components/schemas/Employer'
- $ref: '#/components/schemas/Employee'
Worker:
title: Worker
type: object
properties:
name:
type: string
discriminator: "@type"
required:
- name
Employer:
title: Employer
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
hasFullAccess:
type: boolean
required:
- hasFullAccess
Employee:
title: Employee
type: object
allOf:
- $ref: '#/components/schemas/Worker'
- type: object
properties:
registrationTimestamp:
type: string
description: Time of prioritization
format: date-time
registrationDate:
type: string
required:
- registrationDate
Option 6 - ...
Anything other than specified.
What we need clarity on ❓
- What is the recommended way to define inheritance for object arrays (in our case, workers) in AsyncAPI 3.0 with JSON Schema Draft 7?