Delivery Service
The previous post described the second step of the refactoring process, which consisted of splitting the ftgo
database schema and defining an ftgo_delivery_service
schema.
The third step of the refactoring process is to define a standalone Delivery Service
and deploy it.
The following diagram shows the design:
The Delivery Service
’s API consists of:
DeliveryController
DeliveryServiceCommandHandlers
, that will eventuallybe used by the FTGO monolith for scheduling and cancelling deliveriesDeliveryEventPublisher
, that publishes events when a courier’s schedule has been updated.
It’s used instead of database triggers to replicate updates to courier’s schedules to the monolith.
The FTGO monolith
now contains a OrderServiceEventHandlers
, which subscribes to the events published by Delivery Management
and updates its local data.The following diagram shows the new module structure:
There are the following modules:
ftgo-delivery-backend*
- previously these were the ftgo-delivery-service*
modulesftgo-delivery-service
- a new module, which contains the Delivery Service
’s main class and the DeliveryServiceCommandHandlers
.
It reuses the ftgo-delivery-backend
module from the monolith rather than implementing the delivery management logic from scratch.The event-based data integration glue is implemented by classes in the following modules:
ftgo-delivery-backend
- contains the DeliveryEventPublisher
class.ftgo-order-service
- contains the OrderServiceEventHandlers
class.Since these modules are part of the FTGO monolith
, it uses the same event-based mechanism internally.
One benefit of using triggers to synchronize two databases is that it doesn’t require any changes to the code. The synchronization is handled entirely by the database. A significant drawback, however, of using triggers is that it results in tight design-time and runtime coupling between the two databases. There is design-time coupling between the database, because a trigger has knowledge of both databases. There is also runtime coupling since both databases are updated within a single transaction.
Another drawback of using triggers is that the coupling makes it difficult to test the newly extracted service in isolation.
Consider, for example, a test that verifies that the Delivery Service
correctly processes a ScheduleDelivery
command message.
If a trigger replicates updates to a Courier
’s schedule from ftgo_delivery_service
database to the ftgo
database then the test must correctly setup that database as well.
A much better approach is to use events to replicate changes.
The Delivery Service
can, for example, publish domain events when it updates a Courier
’s schedule.
The FTGO application
subscribes to those events and updates its database.
An event-based replication mechanism has the following benefits:
It also has a couple of drawbacks. The first drawback of using events is that you need to change the application code to publish and consume events. In particular, modifying all of the places that publish events in a monolithic application might be prohibitively time consuming and error-prone.
The second drawback of using events to replicate changes is that it is eventually consistent.
Unlike triggers, which execute within the ACID transaction that updates the source database, an event handler runs in a separate database transaction
For example, the FTGO application executes the acceptOrder()
command in a single transaction, which accepts the Order
in the ftgo
database, schedules the Delivery
in the ftgo_delivery_service
database, and replicates the changes (via a trigger) back to the ftgo
database.
In contrast, the event-based design uses two transactions.
The first transaction accepts the Order
in the ftgo
database, and schedules the Delivery
in the ftgo_delivery_service
database.
The second transaction replicates the changes back to the ftgo
database.
As a result, the acceptOrder()
command no longer updates the Courier
’s schedule.
In the future, the FTGO application
might use events.
But for now, we’ll just change Delivery Management
to publish events it’s a relatively small change that makes it much easier to test the Delivery Service
.
DeliveryServiceComponentTest
Because the Delivery Service
uses events rather than triggers to replicate changes to the FTGO application
it’s straightforward to test the service in isolation.
DeliveryServiceComponentTest
implements a component test for the Delivery Service
.
The following diagram shows how this test works:
It sets up couriers and restaurants (normally replicated from the ftgo
database via triggers) using JPA.
DeliveryServiceComponentTest
then sends a command message to the Delivery Service
and asserts that it publishes the expected events.
Delivery Service
Like the FTGO application
, the Delivery Service
is a Spring Boot application that is deployed a Docker container.
The ftgo-delivery-service/Dockerfile
file defines the container image.
The docker-compose.yml
file defines at ftgo-delivery-service
container along with the infrastructure services needed for transactional messaging: Apache Zookeeper, Apache Kafka, and Eventuate Tram CDC.
These changes are in the extract-delivery-service-03-define-service
branch and consist of the following commits:
ftgo-delivery-service*
modules to ftgo-delivery-backend*
Delivery Service
Delivery Service
Delivery Service
.Microservices.io is brought to you by Chris Richardson. Experienced software architect, author of POJOs in Action, the creator of the original CloudFoundry.com, and the author of Microservices patterns.
Chris helps clients around the world adopt the microservice architecture through consulting engagements, and training workshops.
Chris teaches comprehensive workshops for architects and developers that will enable your organization use microservices effectively.
Avoid the pitfalls of adopting microservices and learn essential topics, such as service decomposition and design and how to refactor a monolith to microservices.
Learn moreChris offers numerous other resources for learning the microservice architecture.
Want to see an example? Check out Chris Richardson's example applications. See code
Got a specific microservice architecture-related question? For example:
Consider signing up for a two hour, highly focussed, consulting session.
My virtual bootcamp, distributed data patterns in a microservice architecture, is now open for enrollment!
It covers the key distributed data management patterns including Saga, API Composition, and CQRS.
It consists of video lectures, code labs, and a weekly ask-me-anything video conference repeated in multiple timezones.
The regular price is $395/person but use coupon MECNPWNR to sign up for $120 (valid until May 16th, 2023). There are deeper discounts for buying multiple seats.
Take a look at my Manning LiveProject that teaches you how to develop a service template and microservice chassis.
Engage Chris to create a microservices adoption roadmap and help you define your microservice architecture,
Use the Eventuate.io platform to tackle distributed data management challenges in your microservices architecture.
Eventuate is Chris's latest startup. It makes it easy to use the Saga pattern to manage transactions and the CQRS pattern to implement queries.
Engage Chris to conduct an architectural assessment.
Note: tagging is work-in-process
anti-patterns · application api · application architecture · architecting · architecture documentation · assemblage · beer · containers · dark energy and dark matter · deployment · design-time coupling · development · devops · docker · eventuate platform · glossary · hexagonal architecture · implementing commands · implementing queries · inter-service communication · kubernetes · loose coupling · microservice architecture · microservice chassis · microservices adoption · microservicesio updates · multi-architecture docker images · observability · pattern · refactoring to microservices · resilience · sagas · security · service api · service collaboration · service design · service discovery · service granularity · service template · software delivery metrics · success triangle · tacos · team topologies · transaction management · transactional messaging