Asyncapi Project
In this tutorial, you will learn about AsyncAPI Project: Event. We cover key concepts, practical examples, and best practices to help you master this topic.
This project brings together everything you have learned about AsyncAPI. You will design, document, generate, and deploy a complete event-driven microservice system.
Project Overview
Build an order processing platform with four Microservices communicating asynchronously via Kafka. Services include Order Service, Payment Service, Inventory Service, and Notification Service.
What You'll Build
- Complete AsyncAPI specifications for all services
- Kafka topic definitions with schema registry
- Generated TypeScript clients from specs
- Docker Compose deployment with Kafka
- Documentation portal for all events
Why This Project
This project simulates a real-world event-driven microservice architecture. You will face the same challenges: schema design, inter-service contracts, topic configuration, and deployment complexity.
Flow Chart
flowchart TD
A[Order Service] -->|order/created| B[Kafka]
A -->|order/cancelled| B
B --> C[Payment Service]
B --> D[Inventory Service]
B --> E[Notification Service]
C -->|payment/authorized| B
C -->|payment/declined| B
D -->|inventory/reserved| B
D -->|inventory/failed| B
E -->|notification/sent| B
Architecture
Shared Schemas
# schemas/common.yaml
components:
schemas:
Money:
type: object
required: [amount, currency]
properties:
amount:
type: number
multipleOf: 0.01
currency:
type: string
pattern: '^[A-Z]{3}$'
Address:
type: object
properties:
street: { type: string }
city: { type: string }
postalCode: { type: string }
country: { type: string }
OrderItem:
type: object
required: [productId, quantity, price]
properties:
productId: { type: string }
quantity: { type: integer }
price: { $ref: '#/components/schemas/Money' }
Order Service Spec
# order-service.yaml
asyncapi: '2.6.0'
info:
title: Order Service Events
version: '1.0.0'
servers:
kafka:
url: kafka://localhost:9092
protocol: kafka
channels:
order/created:
publish:
operationId: onOrderCreated
message:
payload:
type: object
required: [orderId, customerId, items, total]
properties:
orderId: { type: string }
customerId: { type: string }
items: { type: array, items: { $ref: '../schemas/common.yaml#/components/schemas/OrderItem' } }
total: { $ref: '../schemas/common.yaml#/components/schemas/Money' }
order/payment-processed:
subscribe:
operationId: orderPaymentProcessed
message:
payload:
type: object
properties:
orderId: { type: string }
paymentStatus: { type: string, enum: [authorized, declined] }
Generated Client Usage
// Generated from AsyncAPI spec
import { OrderServiceClient } from './generated/order-service';
const client = new OrderServiceClient({
brokers: ['localhost:9092'],
});
// Publish order created event
await client.publishOrderCreated({
orderId: 'ORD-123',
customerId: 'CUST-456',
items: [{ productId: 'PROD-1', quantity: 2, price: { amount: 29.99, currency: 'USD' } }],
total: { amount: 59.98, currency: 'USD' },
});
// Subscribe to payment processed events
await client.onOrderPaymentProcessed(async (event) => {
console.log(`Order ${event.orderId}: ${event.paymentStatus}`);
if (event.paymentStatus === 'authorized') {
await reserveInventory(event.orderId);
}
});
Docker Compose
version: '3.8'
services:
zookeeper:
image: confluentinc/cp-zookeeper:latest
environment:
ZOOKEEPER_CLIENT_PORT: 2181
kafka:
image: confluentinc/cp-kafka:latest
depends_on: [zookeeper]
ports:
- "9092:9092"
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
schema-registry:
image: confluentinc/cp-schema-registry:latest
depends_on: [kafka]
ports:
- "8081:8081"
environment:
SCHEMA_REGISTRY_HOST_NAME: schema-registry
SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: kafka:9092
order-service:
build: ./services/order-service
depends_on: [kafka, schema-registry]
payment-service:
build: ./services/payment-service
depends_on: [kafka, schema-registry]
inventory-service:
build: ./services/inventory-service
depends_on: [kafka, schema-registry]
notification-service:
build: ./services/notification-service
depends_on: [kafka, schema-registry]
Common Mistakes
| Mistake | Explanation |
|---|---|
| Tight coupling through shared schemas | Changes to shared schemas affect all services; version carefully and communicate changes |
| Skipping schema registry | Without a registry, schema evolution becomes unmanageable and breaks consumers |
| Not testing schema compatibility | Always test that new schema versions are backward compatible with existing consumers |
| Ignoring error channels | Every service should have error/dead-letter channels documented for failed messages |
| Manual topic creation | Use AsyncAPI tooling to automate topic provisioning from the specification |
FAQ
Mini Project
Complete the full event-driven microservice implementation. Extend the system with a shipping service, a dead letter queue handler, and an event replay mechanism. Add OpenTelemetry tracing and a monitoring dashboard showing event flows between services.
What's Next
Learn about WebSocket for real-time communication
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro