This document discusses API design patterns for event-based APIs. It begins with an introduction to the author and overview of popular API styles. It then covers several options for asynchronous API design like webhooks, server-sent events, websockets, and streaming protocols. The remainder discusses specific patterns for event payload design including thin notifications, hypermedia links, schema evolution, and separating internal and external events. It emphasizes putting careful design into event formats as they form a contract like an API.
5. 5
@launchany
Async API Design Practices
•Ask what kinds of questions the event needs to answer:
– What happened?
– Who did it happen to?
– Why did it occur?
•Example #1:
•Example #2:
__________________
7. 7
@launchany
Traditional Message Brokers: Queues and Topics
Point-to-Point Messaging
via Queues
Fanout (Pub/Sub)
via Topics
Component
MessageBroker
Component
Publisher
MessageBroker
Subscriber
Subscriber
Subscriber
Component
Message B
Message A
Message A
Message B
Message A
Message A
Message A
Message A
8. 8
@launchany
Distributed Logs Popularized by Apache Kafka and Apache Pulsar
Topic A
Record1
Record2
Record3
Record4
Record5
Record6
Record7
Record8
Record9
Record10
Consumer BConsumer A
16. 17
@launchany
”…if you’re going to start emitting events from a
piece of software, put just as much care into [event
design] as you would as you do in specifying an
API. Because event formats are a contract, too.”
– Tim Bray
https://www.tbray.org/ongoing/When/201x/2019/11/17/Bits-On-the-Wire
19. 20
@launchany
Thin Event Notification (aka “Thin Events”)
•Broadcast only the necessary details to
notify that an event occurred
•Forces subscribers to fetch additional
details to complete a task
Use when:
•The desire is to prevent subscribers
processing stale data. They are forced to
fetch the latest data due to frequent
changes or potentially delayed processing
23. 24
@launchany
Event-Carried State Transfer
• Broadcasts all known data at the time of the event
• Often contain the entire record, avoiding the need to contact
the source system to conduct further work
Use when:
• Subscribers want a snapshot of the data with the event
• Sharing data state changes through message streaming
(Apache Kafka, Apache Pulsar, etc.) to support replaying
message history.
• Using event sourcing /CQRS to capture state changes over
time
25. 26
@launchany
Structured Event Payloads
• Groups properties as nested structures
• Avoids flat structures that require subscribers to
figure out how properties are grouped
• Helps drive evolvability as property names are
scoped to the parent property (e.g. addressLine1)
Use when:
• Event payloads require complex data structures
• Event payloads have nested 1-to-many
relationships as part of an event payload
27. 28
@launchany
Evolutionary Event Schema
• Only add new payload properties that have
default values or are not required
• Don’t delete existing properties unless they
offer a default value (even when missing in
future events)
• Don’t rename property names
Use when:
• When you need to make changes to your
event payload structure but don’t want to
break existing subscribers
29. 30
@launchany
Offline and Error Recovery Support
• Supplement event notification channels with
APIs that allow offline consumers to catch-
up
• Also allows consumers to identify and
troubleshoot failed deliveries
Use when:
• Consumers have limited or no access to
internal mechanisms to detect errors
• When offline support is necessary to keep
consumers in-sync
31. 32
@launchany
Separate Internal and External Events
• Design internal events for coordinating
implementation details
• Design external events for notification and
extensibility
Use when:
• Event-driven architecture is being used
internally, but external events are desired
• Prevent leaking implementation details or
special knowledge of how your internal
systems operate
{
"event": {
"type": "paymentProcessed",
"orderId" : "abc123",
...
}
}
{
"eventType": "authorized",
"transactionId" : "ffe36193abc",
"authorizationServer": "auth7.mycompany.com",
"merchantId" : ”m0043286410",
"transactionAmountInCents" : "20899",
"transactionCurrency" : "USD",
...
}
vs.
34. 35
@launchany
Streaming and Eventing Today
•APIs deliver capabilities through commands and queries
•Events and streaming provide extensibility of our API platform
•Discovery via OpenAPI Spec + AsyncAPI (https://asyncapi.com)
•Services and Serverless (FaaS and iPaaS) are the integration glue
Rewards API
Redeem Svc
Register Svc
Redemption Stream
Redemption Event
onRedemptionEvent()
APIs Services
Streaming
& Eventing
Services, Stream Processors
& Functions-as-a-Service
Redemption Processor
Service