Event consumers and event consumption best practices
Event consumers are applications on the receiving end. They set up subscription policies to identify the events that are of interest to them. As you get started with Amazon EventBridge, here are a few tips and best practices for event consumers to keep in mind:
Consumer applications may receive duplicate events and should be idempotent.
In event-driven computing, in the majority of cases, the event delivery is guaranteed to be at least once (as opposed to exactly once or at most once). If you don’t properly account for this, it can cause severe consequences. Imagine your bank account getting debited twice for a purchase you made!
Building idempotency into an application that reacts upon receipt of events is the most critical measure to implement.
Storing the event data while processing it has benefits.
Depending on the event consumer’s logic, the event processing may happen in near real time or with a delay. A practice often adopted by event subscribers is to store the event data—temporarily or long-term—before acting on it. This is a form of storage-first pattern, which you will learn about in Chapter 5.
There are several benefits to this practice. Primarily, it helps to alleviate the problem of events potentially being received more than once by providing a register that can be checked for duplicates before handling an event. In addition, storing the events eases the retry burden on the consumer application; if a downstream application goes down, for example, it won’t need to request that the producer resend all of the events that application needs to process.
Ordering of events is not guaranteed.
Maintaining the order of events in a distributed event-driven architecture with multiple publishers and subscribers is hard. EventBridge does not guarantee event ordering. If the order of events is crucial, you’ll need to work with the event producers to add sequence numbering. If that’s not possible, subscribers can implement sorting based on the event creation timestamps to put them into the correct order.
Avoid modifying events before relaying them.
There are situations where applications engage in an asynchronous chain of actions known as the event relay pattern: the service receives an event, performs an action, and emits an event for a downstream service. In such situations, the subscriber should never modify the source event and publish a modified version. It must always emit a new event with its identity as publisher and the schema it is responsible for.
Collect events that failed to reach the target consumer.
In a resilient event-driven architecture, a consumer may have all the measures it needs to process an event successfully—but what happens if the event gets lost in transit and does not arrive, or if the consumer experiences an unforeseen outage?
EventBridge retries event delivery until successful for up to 24 hours. If it fails to deliver an event to the target, it can send the failed event to a dead letter queue (DLQ) for later processing. As you saw earlier, you can also use EventBridge’s archive and replay feature to reduce the risk of missing critical business events.
Note
CloudEvents is a specification for describing event data in a common way. It’s supported by the Cloud Native Computing Foundation (CNCF). Adopting CloudEvents as the standard for defining and producing your event payloads will ensure your events remain interoperable, understandable, and predictable, particularly as usage increases across the domains in your organization.
AsyncAPI is the industry standard for defining asynchronous APIs, and it can be used to describe and document message-driven APIs in a machine-readable format. Whereas the CloudEvents specification constrains the schema of your event payloads, AsyncAPI helps you to document the API for producing and consuming your events. AsyncAPI is to event-driven interfaces as OpenAPI is to RESTful APIs.