The previous post described the first step of the refactoring process, which consisted of moving the delivery management code into its own ftgo-delivery-service
module.
It left the database unchanged and the newly defined JPA @Entity
classes in the ftgo-delivery-service
module were mapped to the existing database tables.
The Delivery
entity was mapped to the Order
entity’s ORDERS
table.
The second step of the refactoring process splits the database and defines a separate ftgo_delivery_service
database for the ftgo-delivery-service
module.
The following diagram shows the resulting structure:
The changes are primarily in this Git commit.
The following Flyway-based schema migrations in ftgo-flyway/src/main/resources/db/migration
transform the database:
V2__split_courier.sql
V3__replica_restaurant.sql
V4__extract_into_delivery.sql
V5__FK_constraints.sql
These migrations create the tables in the ftgo_delivery_service
database and populate them with data from the monolith’s ftgo
database.
They also define triggers, which replicate data between the two databases.
Some triggers replicate updates to data owned by the FTGO monolith, such as Couriers
and Restaurants
, to ftgo-delivery-service
module’s database.
The other triggers replicate changes to data owned by the ftgo-delivery-service
module to the monolith’s database in order to make it accessed by the read-only columns described in the previous post.
For example, when the ftgo-delivery-service
updates Courier.availability
a trigger updates the corresponding column in the ftgo
database.
Let’s take a look at each of these schemas.
V2__split_courier.sql
This migration defines the courier
and courier_actions
tables in the ftgo_delivery_service
database and populates them with data from the ftgo.courier
and ftgo.courier_actions
tables.
It defines several triggers that synchronize data between the two schemas.
The first two replicate changes made to the ftgo_delivery_service
database to the ftgo
database:
ftgo_delivery_service.courier_availability_updated
- replicates ftgo_delivery_service.courier.available
to ftgo.courier.available
ftgo_delivery_service.courier_actions_created
- replicates inserts into ftgo_delivery_service.courier_actions
to ftgo.courier.courier_actions
(TODO what about deletes)The other two triggers replicate changes made to the ftgo
database to the ftgo_delivery_service
database:
ftgo.courier_created
- replicates inserts into ftgo.courier
to ftgo_delivery_service.courier
ftgo.courier_updated
- replicates updates of ftgo.courier
to ftgo_delivery_service.courier
V3__replica_restaurant.sql
This migration defines the restaurant
table in the ftgo_delivery_service
database and populates it with restaurants from ftgo.restaurant
.
It also defines a trigger that replicates inserts into ftgo.restaurant
table to the ftgo_delivery_service.restaurant
table.
TODO what about UDs
V4__extract_into_delivery.sql
This migration defines the delivery
table in the ftgo_delivery_service
database and populates it with deliveries from ftgo.delivery
.
It also defines a trigger that replicates updates of the ftgo_delivery_service.assigned_courier_id
column to the ftgo.delivery
table.
V5__FK_constraints.sql
This migration creates foreign key constraints between the newly defined tables.
In addition to the schema changes, there are a few code changes.
First, the JPA entities in the ftgo-delivery-module
are mapped to new databases tables.
For example, Delivery
is mapped to the delivery
table:
@Entity
@Table(name = "delivery", catalog = "ftgo_delivery_service")
@Access(AccessType.FIELD)
@DynamicUpdate
public class Delivery {
...
Second, the DeliveryState
enum is simplified since it no longer needs to mirror OrderState
.
It now just defines values that correspond to the state of the Delivery
.
Third, because Delivery
no longer shares a table with Order
the DeliveryService.scheduleDelivery()
method can no longer load the Delivery
.
Instead, it must create the Delivery
:
public class DeliveryServiceImpl implements DeliveryService, DeliveryCourierService {
private DeliveryRepository deliveryRepository;
public void scheduleDelivery(LocalDateTime readyBy, Long orderId, long restaurantId, Address deliveryAddress) {
...
delivery = deliveryRepository.save(delivery);
...
}
...
extract-delivery-service-02-split-db
branch in the main repository.
This refactoring is primarily in this commit.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