Skip to content

allOf (Composition)

Soxom flattens allOf schemas into composite types, preserving model references for inheritance patterns.

components:
schemas:
# Base schema with common fields
TimestampedResource:
type: object
properties:
created_at:
type: string
format: date-time
readOnly: true
updated_at:
type: string
format: date-time
readOnly: true
# Composed schema using allOf
User:
allOf:
- $ref: '#/components/schemas/TimestampedResource'
- type: object
required:
- id
- email
- name
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
status:
type: string
enum: [active, inactive]
// Base interface
interface TimestampedResource {
readonly createdAt: Date;
readonly updatedAt: Date;
}
// Composed interface extends base
interface User extends TimestampedResource {
id: string;
email: string;
name: string;
status?: 'active' | 'inactive';
}

Soxom handles allOf differently based on its contents:

When allOf includes $ref, Soxom uses inheritance/composition:

User:
allOf:
- $ref: '#/components/schemas/BaseModel' # → extends/embeds
- $ref: '#/components/schemas/Auditable' # → extends/embeds
- type: object
properties: # → own properties
name:
type: string

Inline object schemas are flattened into the parent:

User:
allOf:
- type: object # Flattened
properties:
id:
type: string
- type: object # Flattened
properties:
name:
type: string

Results in:

interface User {
id: string;
name: string;
}
components:
schemas:
Animal:
type: object
properties:
name:
type: string
age:
type: integer
Dog:
allOf:
- $ref: '#/components/schemas/Animal'
- type: object
properties:
breed:
type: string
interface Animal {
name: string;
age: number;
}
interface Dog extends Animal {
breed: string;
}
components:
schemas:
Timestamped:
type: object
properties:
created_at:
type: string
format: date-time
Identifiable:
type: object
properties:
id:
type: string
format: uuid
User:
allOf:
- $ref: '#/components/schemas/Timestamped'
- $ref: '#/components/schemas/Identifiable'
- type: object
properties:
email:
type: string
interface Timestamped {
createdAt: Date;
}
interface Identifiable {
id: string;
}
interface User extends Timestamped, Identifiable {
email: string;
}

When the same property appears multiple times, the last definition wins:

Base:
type: object
properties:
status:
type: string
Extended:
allOf:
- $ref: '#/components/schemas/Base'
- type: object
properties:
status:
type: string
enum: [active, inactive] # More specific

Result uses the more specific enum type.

Required properties are merged from all schemas:

Base:
type: object
required:
- id
properties:
id:
type: string
User:
allOf:
- $ref: '#/components/schemas/Base'
- type: object
required:
- email
properties:
email:
type: string

User has both id and email as required.

  1. Use $ref for shared schemas - Enables proper inheritance
  2. Keep base schemas small - Single responsibility
  3. Avoid deep inheritance - 2-3 levels maximum
  4. Document compositions - Use descriptions
  5. Prefer mixins over deep hierarchies
ApiResponse:
type: object
properties:
success:
type: boolean
timestamp:
type: string
format: date-time
UserResponse:
allOf:
- $ref: '#/components/schemas/ApiResponse'
- type: object
properties:
data:
$ref: '#/components/schemas/User'
UserBase:
type: object
properties:
email:
type: string
name:
type: string
UserCreate:
allOf:
- $ref: '#/components/schemas/UserBase'
- type: object
required:
- email
- name
- password
properties:
password:
type: string
UserUpdate:
allOf:
- $ref: '#/components/schemas/UserBase'
# All fields optional for updates
  • anyOf - How Soxom handles anyOf
  • Naming - Naming conventions