- Hi, my name is Talia Nassi,
and I'm a senior developer advocate here at AWS Serverless.
Two options when building web applications
are request-response and event-driven architecture.
In request-response architecture,
an application's components communicate via API calls.
The client sends a request and expects a response
before performing the next task.
In event-driven architecture, the client generates an event
and can immediately move on to its next task.
Different parts of the application
then respond to the event as needed.
When starting to build a new application,
many developers default to a request-response architecture.
A request-response architecture tightly integrates
components and those components communicate
via synchronous calls.
While a request-response approach is easier
to get started with, it can quickly become challenging
as your application grows in complexity.
In a typical e-commerce application that uses
a synchronous API, the client makes a request
to place an order.
And the order service sends the request downstream
to an invoice service.
If successful the order responds with a success message,
confirmation number, et cetera.
And in this initial stage,
this is a straightforward connection
between the two services.
The challenge comes when you add more services
that integrate with the order service.
If you add a fulfillment service and a forecasting service,
the order service has more responsibilities
and more complexity.
The order service must know how to call each service's API
from the API call structure to the API's retry semantics.
If there are any backwards incompatible changes to the APIs,
the order service team must update them.
The system forwards heavy traffic spikes
to the order service's dependency
which may not have the same scaling capabilities.
Also dependent services transmit errors
back up stack to the client.
Now you add new downstream services for fulfillment
and shipping orders to the e-commerce application.
In the happy path, everything works as expected.
The order service triggers invoicing,
payment systems and updates forecasting.
Once payment clears, this triggers the fulfillment
and packing of the order.
And then you inform the shipping service
to request tracking information.
However, what happens if the fulfillment center
cannot find the product because they are out of stock?
Fulfillment might have to alert the invoice service
then reverse the payment or issue a refund.
Would the system trigger shipping if fulfillment fails?
Maybe not since it's directly before shipping
in the chain of events.
Forecasting will also need to be updated
to reflect this change.
This remediation workflow is all just to fix
one of the many potential unhappy paths that can occur
in a synchronous API driven e-commerce application.
In a synchronously integrated application,
teams need to coordinate any new services
that are added to the application.
This can slow down each development team's ability
to release new features.
Imagine your team works on the payment service,
but you weren't told that another team added a new service,
a rewards service.
What now happens when the fulfillment service errors?
Fulfillment maybe orchestrates all of the other services.
Your payment team gets a message and you undo the payment,
but you don't know who handles retries and error logic.
What happens if the rewards service changes vendors
and has a new API?
Did your team know about that?
Ultimately, it's very hard to coordinate
these orchestrations and workflows
as systems become more and more complex
and as you add more services.
Event-driven architecture can help solve the problems
of the close coordination of microservices,
error handling and retries
and coordination between development teams.
In event-driven architecture,
the publisher emits an event
which is acknowledged by the event bus.
The event bus routes events to subscribers
which process events with self-contained business logic.
There is no direct communication
between publishers and subscribers.
Decoupled applications enable teams
to act more independently, which increases their velocity.
For example, with an API-based integration,
if my team wants to know about some change
that happened in another team's microservice,
I have to ask that team to make an API call to my service.
That means I have to deal with authentication,
coordination with the other team
over the structure of the API call, et cetera.
This causes a lot of back and forth between teams
which slows down development time.
With an event-driven application,
I can simply subscribe to events sent from your microservice
and the event router, like Amazon EventBridge,
takes care of routing the event,
handling authentication, et cetera.
Another reason to migrate to event-driven architecture
is to be able to handle unpredictable traffic.
E-commerce websites like amazon.com have variable amounts
of traffic depending on the day.
Once you place an order, a bunch of things happen.
First, Amazon checks your credit card
to make sure you can pay.
Then Amazon has to get the merchandise off the shelves
and onto the trucks and so on and so on.
That all happens in an Amazon warehouse.
There's no synchronous API call for the Amazon backends
to package and ship products.
After the system confirms your payment,
the front end puts together some information
describing the event and puts your account number,
credit card info and what you bought in a packaged event
and puts it into the cloud and onto a queue.
Later, another piece of software will pull it off
and start the packing, the shipping, et cetera.
The key point about this process is that all of these things
can run at different rates.
Normally, the rate at which people click place order
and the rate at which warehouses can get the boxes
out of the doors are roughly equivalent.
However, on days like Prime Day or Black Friday,
people hit that button immensely faster
than the warehouses can operate, and that's okay
because the backend will work itself through.
E-commerce applications like amazon.com
need to be able to scale up to handle unpredictable traffic.
When a customer places an order, an event router
like Amazon EventBridge receives the events
and all of the downstream microservices are able
to pick up the order event for processing.
Because each of the microservices can fail independently,
there are no single points of failure.
Event-driven architectures promote
development team independence due to loose coupling
between publishers and subscribers.
Applications are free to subscribe to events
with routing requirements and business logic
that are separate from the publisher and other subscribers.
This allows publishers and subscribers
to change independently of each other,
providing more flexibility to the overall architecture.
Decoupled applications also allow you
to build new features faster.
Adding new features or extending existing ones
is much simpler with event-driven architectures
because all you have to do is choose the event
you need to trigger your new feature
and then subscribe to it.
There is no need to modify any of your existing services
to add new functionality.
To learn more about event-driven architecture
and Amazon EventBridge head to serverlessland.com
where you'll find more content from me and my team.
I'm Talia Nassi. Thanks for tuning in.