Event-Driven Architecture (EDA) has become increasingly popular, especially in systems utilizing microservices. Fundamentally it means you are using events to trigger and communicate between decoupled components within an application, as opposed to communicating directly via APIs in a Request/Reponse driven manner.
An event can be anything from a user action, like adding an item to a shopping cart, to a system update, such as an order being shipped. These events can carry detailed information or simply act as notifications of a particular state change.
Event-Driven Architectures typically consists of three main components:
This architecture allows for services to be highly decoupled, meaning they operate independently of each other, which brings several benefits to the development process and system operation.
Scalability and Independent Failure: In an EDA, services are only aware of the event router and not each other. This decoupling allows services to scale and fail independently. If one component experiences a failure, it doesn't directly impact the others, enhancing the system's overall resilience.
Development Agility: Developers can focus on their specific services without worrying about the intricate details of communication between different parts of the system. The event router handles the distribution of events, which streamlines the development process and accelerates time to market.
Simplified Auditing and Policy Enforcement: Having a centralized event router simplifies the auditing of system activities and the enforcement of security and access policies. It becomes easier to control who can publish or subscribe to certain events and secure sensitive data in transit and at rest.
Cost Efficiency: EDA is inherently efficient, operating on a push-based mechanism where actions are taken on-demand in response to events. This reduces the need for continuous polling, saving on resources like network bandwidth and CPU usage.
Event-Driven Architectures introduce new requirements for maintaining a productive developer workflow:
Pub/Sub systems are a natural fit for implementing an EDA. They provide the necessary infrastructure for event producers to publish messages that are then consumed by interested subscribers. This model supports the dynamic and decoupled nature of EDA, allowing for flexible, scalable, and resilient system designs. Learn more about Pub/Sub.
Encore provides a fully type-safe implementation of Pub/Sub via an Open Source Backend Framework, available for Go and TypeScript. It lets you define the common distributed systems resources like services, databases, cron jobs, and Pub/Sub, as type-safe objects in your application code.
With the Framework you only define infrastructure semantics — the things that matter to your application's behavior — not configuration for specific cloud services. Encore parses your application and builds a graph of both its logical architecture and its infrastructure requirements, it then automatically generates boilerplate and orchestrates the relevant infrastructure for each environment. This means your application code can be used to run locally, test in preview environments, and provision and deploy to cloud environments on AWS and GCP.
This approach completely removes the need for mocks and emulators, and allows you to work offline and run you application locally. You also get the added benefit of avoiding having a separate infrastructure configuration like Terraform, since the application code becomes the source of truth for your application's infrastructure requirements.
When your application is deployed to your cloud, there are no runtime dependencies on Encore and there is no proprietary code running in your cloud.
If you want a Pub/Sub Topic, you declare it directly in your application code, like so:
import "encore.dev/pubsub"
type User struct { /* fields... */ }
var Signup = pubsub.NewTopic[*User]("signup", pubsub.TopicConfig{
DeliveryGuarantee: pubsub.AtLeastOnce,
})
// Publish messages by calling a method
Signup.Publish(ctx, &User{...})
To run your application, you simply use encore run
. Encore will automatically set up the local infrastructure and generate the boilerplate code necessary.
You also get a local development dashboard with distributed tracing to help you understand and debug application behavior with ease.
Your code doesn't change when you want to deploy to the cloud. Encore will generate the necessary boilerplate and provision the necessary infrastructure in all environments:
Event-Driven Architecture offers a flexible and scalable way to design and operate complex systems, especially those based on microservices. By leveraging Pub/Sub mechanisms, you can create decoupled systems that are resilient to failures, easy to scale, and quick to develop. Success with EDA requires a thoughtful approach and the appropriate tooling for local development, observability, and documentation.