AsyncAPI Schemas — Complete Guide
In this tutorial, you will learn about AsyncAPI Schemas. We cover key concepts, practical examples, and best practices to help you master this topic.
Schemas define the structure of message payloads in AsyncAPI. They ensure data consistency, enable validation, and drive Code Generation. This lesson covers schema Design Patterns, reuse strategies, and best practices.
What You'll Learn
- Schema organization and reuse
- JSON Schema features for event data
- Schema composition and inheritance
- Schema versioning strategies
- Cross-service schema sharing
Why It Matters
Well-designed schemas prevent data inconsistencies between producers and consumers. Reusable schema components reduce duplication and make specifications easier to maintain.
Real-World Use
A large enterprise maintains a shared schema Repository for all event payloads. Services reference schemas from this repository in their AsyncAPI specs, ensuring consistent data structures across the entire organization.
Flow Chart
flowchart LR
A[Schemas] --> B[Simple Types]
A --> C[Composition]
A --> D[Reusability]
B --> E[string, number, boolean]
C --> F[allOf, oneOf, anyOf]
C --> G[$ref References]
D --> H[Component Schemas]
D --> I[Shared Schema Registry]
Code Examples
Example 1: Schema Organization with Refs
components:
schemas:
Address:
type: object
description: Physical address
required:
- street
- city
- country
properties:
street:
type: string
city:
type: string
state:
type: string
postalCode:
type: string
country:
type: string
Customer:
type: object
description: Customer information
required:
- customerId
- email
properties:
customerId:
type: string
format: uuid
email:
type: string
format: email
firstName:
type: string
lastName:
type: string
address:
$ref: '#/components/schemas/Address'
phone:
type: string
OrderItem:
type: object
required:
- productId
- quantity
- price
properties:
productId:
type: string
quantity:
type: integer
minimum: 1
price:
type: number
minimum: 0
OrderCreated:
type: object
required:
- orderId
- customer
- items
- total
properties:
orderId:
type: string
customer:
$ref: '#/components/schemas/Customer'
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
total:
type: number
currency:
type: string
default: USD
Expected output: Reusable schema components with nested references, enabling composition of complex event payloads.
Example 2: Schema Composition Patterns
components:
schemas:
BaseEvent:
type: object
required:
- eventId
- timestamp
- source
properties:
eventId:
type: string
format: uuid
timestamp:
type: string
format: date-time
source:
type: string
correlationId:
type: string
OrderEvent:
allOf:
- $ref: '#/components/schemas/BaseEvent'
- type: object
required:
- orderId
properties:
orderId:
type: string
orderType:
type: string
enum:
- standard
- express
- scheduled
OrderCreated:
allOf:
- $ref: '#/components/schemas/OrderEvent'
- type: object
properties:
customerId:
type: string
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
OrderCancelled:
allOf:
- $ref: '#/components/schemas/OrderEvent'
- type: object
properties:
reason:
type: string
cancelledBy:
type: string
Expected output: Schema inheritance using allOf, where OrderCreated and OrderCancelled extend OrderEvent, which extends BaseEvent.
Example 3: Schema with Enums and Constraints
components:
schemas:
OrderStatus:
type: string
enum:
- PENDING
- CONFIRMED
- PROCESSING
- SHIPPED
- DELIVERED
- CANCELLED
- REFUNDED
PaymentMethod:
type: string
enum:
- CREDIT_CARD
- DEBIT_CARD
- PAYPAL
- BANK_TRANSFER
- CRYPTO
Money:
type: object
required:
- amount
- currency
properties:
amount:
type: number
multipleOf: 0.01
minimum: 0
currency:
type: string
pattern: '^[A-Z]{3}$'
example: USD
PaginatedResponse:
type: object
required:
- data
- total
- page
- pageSize
properties:
data:
type: array
total:
type: integer
minimum: 0
page:
type: integer
minimum: 1
pageSize:
type: integer
minimum: 1
maximum: 100
hasMore:
type: boolean
Expected output: Schemas with enumerated values, monetary constraints, and pagination fields with validation rules.
Common Mistakes
| Mistake | Explanation |
|---|---|
| Duplicating schemas across messages | Define shared schemas once in components and reference them with $ref |
| Using deeply nested schemas | Deep nesting makes payloads hard to work with; flatten to 2-3 levels |
| Not using enum for constrained values | Enums provide self-documenting allowed values and enable validation |
| Forgetting to version schemas | Schema evolution needs versioning; include version in the schema or message |
| Ignoring examples | Every schema should have at least one example to guide consumers |
| Making schemas too permissive | Use required fields, patterns, and constraints to enforce data quality |
Practice Questions
- How do you reuse a schema across multiple messages in AsyncAPI?
- What is the difference between
allOf,oneOf, andanyOf? - How do you define an enumerated type in a schema?
- How do you handle schema evolution and breaking changes?
- What is the best practice for organizing schemas across multiple AsyncAPI documents?
Challenge
Design a complete schema library for a hotel booking system. Include schemas for hotels, rooms, guests, reservations, payments, and reviews. Use composition patterns (base event, specific events) and ensure all schemas have proper validation constraints and examples.
FAQ
Mini Project
Build a shared schema repository for a multi-service architecture. Include common schemas (Money, Address, PaginatedResponse, BaseEvent), domain-specific schemas (Order, Product, Customer), and schema evolution documentation. Write a script that validates all schemas and generates documentation.
What's Next
Build a complete AsyncAPI project
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro