Skip to content

Commit c51d4e9

Browse files
committed
restructured into services
1 parent d4c79a1 commit c51d4e9

File tree

182 files changed

+2175
-2204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+2175
-2204
lines changed

README.md

+48-44
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ mvn spring-boot:run
1010

1111
## Table of Contents
1212

13-
- [Domain Services](#domain-services)
13+
- [Domains](#domains)
1414
+ [Core Domain](#core-domain)
1515
+ [Supporting Subdomains](#supporting-subdomains)
16-
+ [Services Event Workflow](#services-event-workflow)
16+
+ [Event Workflow](#event-workflow)
1717
+ [Services Dependencies](#services-dependencies)
1818
- [Architectural Overview](#architectural-overview)
1919
+ [Screaming Architecture](#screaming-architecture)
2020
+ [Packaging](#packaging)
2121
+ [Assembling](#assembling)
2222
+ [Anatomy of a Service](#anatomy-of-a-service)
2323

24-
## Domain Services
24+
## Domains
2525

2626
Several [Business Capabilities][vcha] have been identified:
2727

@@ -64,25 +64,25 @@ Later, we can think about more supporting domains (not implemented in this proje
6464
- provide help
6565
- loyalty program
6666

67-
The e-commerce system is a web application using a **Catalogue** service implementing the [Backends For Frontends (BFF)][bff] pattern.
67+
The e-commerce system is a web application using a **Portal** component implementing the [Backends For Frontends (BFF)][bff] pattern.
6868

6969
[bff]: https://samnewman.io/patterns/architectural/bff/
7070

71-
### Services Event Workflow
71+
### Event Workflow
7272

73-
The communication among services is implemented via events:
73+
The communication among domains is implemented via events:
7474

75-
![Service Event Workflow](doc/services-event-workflow.png)
75+
![Event Workflow](doc/event-workflow.png)
7676

7777
When the customer places an order the following process starts up (the happy path):
7878

79-
1. Shipping service prepares a new delivery.
80-
1. Sales service creates a new order and publishes the `OrderPlaced` event.
81-
1. Shipping service accepts the delivery.
82-
1. Billing service collects payment for the order and publishes the `PaymentCollected` event.
83-
1. Warehouse service fetches goods from the stock and publishes the `GoodsFetched` event.
84-
1. Shipping service dispatches the delivery and publishes the `DeliveryDispatched` event.
85-
1. Warehouse service updates the stock.
79+
1. Shipping prepares a new delivery.
80+
1. Sales creates a new order and publishes the `OrderPlaced` event.
81+
1. Shipping accepts the delivery.
82+
1. Billing collects payment for the order and publishes the `PaymentCollected` event.
83+
1. Warehouse fetches goods from the stock and publishes the `GoodsFetched` event.
84+
1. Shipping dispatches the delivery and publishes the `DeliveryDispatched` event.
85+
1. Warehouse updates the stock.
8686

8787
There is only the basic "happy path" workflow implemented with a big room for improvement, for example when Shipping doesn't get bot Events within a time period, the delivery process should be cancelled etc..
8888

@@ -96,7 +96,7 @@ The actual dependencies come only from Listeners which fulfill the role of the A
9696

9797
Events contain no Domain Objects.
9898

99-
For communication across Services an Event Publisher abstraction is used, located in the package `..ecommerce.common`. The interface is an Output Port (in the Hexagonal Architecture) and as a cross-cutting concern is its implementation injected by the Application.
99+
For communication across Services an Event Publisher abstraction is used, located in the package `..ecommerce.common.events`. The interface is an Output Port (in the Hexagonal Architecture) and as a cross-cutting concern is its implementation injected by the Application.
100100

101101
## Architectural Overview
102102

@@ -146,7 +146,7 @@ As shown in the previous section, the code is structured by the domain together
146146

147147
Such a packaging style is the first step for a further modularization.
148148

149-
The semantic of a package is following: `company.product.domain.aggregate.impl`, where `aggregate` and `impl` are optional. Full example: `com.ttulka.ecommerce.billing.payment.jdbc`.
149+
The semantic of a package is following: `company.product.domain.service.[entity|impl]`, where `entity` and `impl` are optional. Full example: `com.ttulka.ecommerce.billing.payment.jdbc`.
150150

151151
### Assembling
152152

@@ -155,63 +155,67 @@ To show that the Monolith architectural pattern is not equal to the Big Ball Of
155155
The services can be further cut into separate modules (eg. Maven artifacts) by feature:
156156
```
157157
com.ttulka.ecommerce:ecommerce-application
158-
com.ttulka.ecommerce:billing-service
159-
com.ttulka.ecommerce:sales-service
160-
com.ttulka.ecommerce:shipping-service
161-
com.ttulka.ecommerce:warehouse-service
158+
com.ttulka.ecommerce.sales:catalog-service
159+
com.ttulka.ecommerce.sales:cart-service
160+
com.ttulka.ecommerce.sales:order-service
161+
com.ttulka.ecommerce.billing:payment-service
162+
com.ttulka.ecommerce.shipping:delivery-service
163+
com.ttulka.ecommerce.warehouse:warehouse-service
162164
```
163165

164166
Or by [component](https://blog.ttulka.com/package-by-component-with-clean-modules-in-java):
165167
```
166-
com.ttulka.ecommerce:billing-domain
167-
com.ttulka.ecommerce:billing-jdbc
168-
com.ttulka.ecommerce:billing-rest
169-
com.ttulka.ecommerce:billing-events
170-
com.ttulka.ecommerce:billing-listeners
168+
com.ttulka.ecommerce.billing:payment-domain
169+
com.ttulka.ecommerce.billing:payment-jdbc
170+
com.ttulka.ecommerce.billing:payment-rest
171+
com.ttulka.ecommerce.billing:payment-events
172+
com.ttulka.ecommerce.billing:payment-listeners
171173
```
172174

173175
In detail:
174176
```
175-
com.ttulka.ecommerce:billing-domain
177+
com.ttulka.ecommerce.billing:payment-domain
176178
..billing
177179
payment
178180
Payment
179181
PaymentId
180-
ReferenceId
181-
Money
182-
CollectPayment
183-
FindPayments
184-
com.ttulka.ecommerce:billing-jdbc
182+
CollectPayment
183+
FindPayments
184+
com.ttulka.ecommerce.billing:payment-jdbc
185185
..billing.payment.jdbc
186186
PaymentJdbc
187-
PaymentsJdbc
188-
com.ttulka.ecommerce:billing-rest
189-
..billing.rest
187+
CollectPaymentJdbc
188+
FindPaymentsJdbc
189+
com.ttulka.ecommerce.billing:payment-rest
190+
..billing.payment.rest
190191
PaymentController
191-
com.ttulka.ecommerce:billing-events
192-
..billing
192+
com.ttulka.ecommerce.billing:payment-events
193+
..billing.payment
193194
PaymentCollected
194-
com.ttulka.ecommerce:billing-listeners
195-
..billing.listeners
196-
OrderPlacedListener
195+
com.ttulka.ecommerce.billing:payment-listeners
196+
..billing.payment.listeners
197+
OrderPlacedListener
197198
```
198199

199200
Which can be brought together with a Spring Boot Starter, containing only Configuration classes and dependencies on other modules:
200201
```
201-
com.ttulka.ecommerce:billing-spring-boot-starter
202-
..billing
203-
payment.jdbc
202+
com.ttulka.ecommerce.billing:payment-spring-boot-starter
203+
..billing.payment
204+
jdbc
204205
PaymentJdbcConfig
205206
listeners
206-
BillingListenersConfig
207+
PaymentListenersConfig
207208
META-INF
208209
spring.factories
209210
```
210211

211-
Note: Events are actually part of the domain, that's why they are in the package `..ecommerce.billing` and not in `..ecommerce.billing.events`. They are in a separate module to break the build cyclic dependencies: a dependent module (Listener) needs to know only Events and not the entire Domain.
212+
Note: Events are actually part of the domain, that's why they are in the package `..ecommerce.billing.payment` and not in `..ecommerce.billing.payment.events`. They are in a separate module to break the build cyclic dependencies: a dependent module (Listener) needs to know only Events and not the entire Domain.
212213

213214
### Anatomy of a Service
214215

216+
**[Service](http://udidahan.com/2010/11/15/the-known-unknowns-of-soa/)** is the technical authority for a specific business capability.
217+
- Single domain can contain multiple services (for example, Sales domain contains Catalog, Cart and Order services).
218+
215219
**Application** is a deployment unit. A monolithic Application can have more Services.
216220
- Bootstrap (application container etc.).
217221
- Cross-cutting concerns (security, transactions, messaging, logging, etc.).
File renamed without changes.

doc/service-anatomy-example.png

1.44 KB
Loading

src/main/java/com/ttulka/ecommerce/billing/CollectPayment.java src/main/java/com/ttulka/ecommerce/billing/payment/CollectPayment.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
package com.ttulka.ecommerce.billing;
1+
package com.ttulka.ecommerce.billing.payment;
22

3-
import com.ttulka.ecommerce.billing.payment.ReferenceId;
4-
import com.ttulka.ecommerce.common.money.Money;
3+
import com.ttulka.ecommerce.common.primitives.Money;
54

65
/**
76
* Collect Payment use-case.

src/main/java/com/ttulka/ecommerce/billing/FindPayments.java src/main/java/com/ttulka/ecommerce/billing/payment/FindPayments.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
package com.ttulka.ecommerce.billing;
2-
3-
import com.ttulka.ecommerce.billing.payment.Payments;
1+
package com.ttulka.ecommerce.billing.payment;
42

53
/**
64
* Find Payments use-case.

src/main/java/com/ttulka/ecommerce/billing/payment/Payment.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.ttulka.ecommerce.billing.payment;
22

3-
import com.ttulka.ecommerce.common.money.Money;
3+
import com.ttulka.ecommerce.common.primitives.Money;
44

55
/**
66
* Payment entity.

src/main/java/com/ttulka/ecommerce/billing/PaymentCollected.java src/main/java/com/ttulka/ecommerce/billing/payment/PaymentCollected.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.ttulka.ecommerce.billing;
1+
package com.ttulka.ecommerce.billing.payment;
22

33
import java.time.Instant;
44

src/main/java/com/ttulka/ecommerce/billing/payment/jdbc/CollectPaymentJdbc.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.ttulka.ecommerce.billing.payment.jdbc;
22

3-
import com.ttulka.ecommerce.billing.CollectPayment;
3+
import com.ttulka.ecommerce.billing.payment.CollectPayment;
44
import com.ttulka.ecommerce.billing.payment.Payment;
55
import com.ttulka.ecommerce.billing.payment.ReferenceId;
66
import com.ttulka.ecommerce.common.events.EventPublisher;
7-
import com.ttulka.ecommerce.common.money.Money;
7+
import com.ttulka.ecommerce.common.primitives.Money;
88

99
import org.springframework.jdbc.core.JdbcTemplate;
1010
import org.springframework.transaction.annotation.Propagation;

src/main/java/com/ttulka/ecommerce/billing/payment/jdbc/FindPaymentsJdbc.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.ttulka.ecommerce.billing.payment.jdbc;
22

3-
import com.ttulka.ecommerce.billing.FindPayments;
3+
import com.ttulka.ecommerce.billing.payment.FindPayments;
44
import com.ttulka.ecommerce.billing.payment.Payments;
55
import com.ttulka.ecommerce.common.events.EventPublisher;
66

src/main/java/com/ttulka/ecommerce/billing/payment/jdbc/PaymentJdbc.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import java.time.Instant;
44
import java.util.UUID;
55

6-
import com.ttulka.ecommerce.billing.PaymentCollected;
76
import com.ttulka.ecommerce.billing.payment.Payment;
7+
import com.ttulka.ecommerce.billing.payment.PaymentCollected;
88
import com.ttulka.ecommerce.billing.payment.PaymentId;
99
import com.ttulka.ecommerce.billing.payment.ReferenceId;
1010
import com.ttulka.ecommerce.common.events.EventPublisher;
11-
import com.ttulka.ecommerce.common.money.Money;
11+
import com.ttulka.ecommerce.common.primitives.Money;
1212

1313
import org.springframework.jdbc.core.JdbcTemplate;
1414

src/main/java/com/ttulka/ecommerce/billing/payment/jdbc/PaymentJdbcConfig.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@
77
import org.springframework.jdbc.core.JdbcTemplate;
88

99
/**
10-
* Configuration for JDBC implementation for Payment domain.
10+
* Configuration for JDBC implementation for Payment service.
1111
*/
1212
@Configuration
1313
class PaymentJdbcConfig {
1414

1515
@Bean
16-
FindPaymentsJdbc findPayments(JdbcTemplate jdbcTemplate, EventPublisher eventPublisher) {
16+
FindPaymentsJdbc findPaymentsJdbc(JdbcTemplate jdbcTemplate, EventPublisher eventPublisher) {
1717
return new FindPaymentsJdbc(jdbcTemplate, eventPublisher);
1818
}
1919

2020
@Bean
21-
CollectPaymentJdbc collectPayment(JdbcTemplate jdbcTemplate, EventPublisher eventPublisher) {
21+
CollectPaymentJdbc collectPaymentJdbc(JdbcTemplate jdbcTemplate, EventPublisher eventPublisher) {
2222
return new CollectPaymentJdbc(jdbcTemplate, eventPublisher);
2323
}
2424
}

src/main/java/com/ttulka/ecommerce/billing/payment/jdbc/PaymentsJdbc.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import com.ttulka.ecommerce.billing.payment.Payments;
1212
import com.ttulka.ecommerce.billing.payment.ReferenceId;
1313
import com.ttulka.ecommerce.common.events.EventPublisher;
14-
import com.ttulka.ecommerce.common.money.Money;
14+
import com.ttulka.ecommerce.common.primitives.Money;
1515

1616
import org.springframework.jdbc.core.JdbcTemplate;
1717

src/main/java/com/ttulka/ecommerce/billing/listeners/OrderPlacedListener.java src/main/java/com/ttulka/ecommerce/billing/payment/listeners/OrderPlacedListener.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
package com.ttulka.ecommerce.billing.listeners;
1+
package com.ttulka.ecommerce.billing.payment.listeners;
22

3-
import com.ttulka.ecommerce.billing.CollectPayment;
3+
import com.ttulka.ecommerce.billing.payment.CollectPayment;
44
import com.ttulka.ecommerce.billing.payment.ReferenceId;
5-
import com.ttulka.ecommerce.common.money.Money;
6-
import com.ttulka.ecommerce.sales.OrderPlaced;
5+
import com.ttulka.ecommerce.common.primitives.Money;
6+
import com.ttulka.ecommerce.sales.order.OrderPlaced;
77

88
import org.springframework.scheduling.annotation.Async;
99
import org.springframework.transaction.event.TransactionalEventListener;

src/main/java/com/ttulka/ecommerce/billing/listeners/BillingListenersConfig.java src/main/java/com/ttulka/ecommerce/billing/payment/listeners/PaymentListenersConfig.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
package com.ttulka.ecommerce.billing.listeners;
1+
package com.ttulka.ecommerce.billing.payment.listeners;
22

3-
import com.ttulka.ecommerce.billing.CollectPayment;
3+
import com.ttulka.ecommerce.billing.payment.CollectPayment;
44

55
import org.springframework.context.annotation.Bean;
66
import org.springframework.context.annotation.Configuration;
77

88
/**
9-
* Configuration for Billing event listeners.
9+
* Configuration for Payment event listeners.
1010
*/
1111
@Configuration
12-
class BillingListenersConfig {
12+
class PaymentListenersConfig {
1313

14-
@Bean("billing-orderPlacedListener") // a custom name to avoid collision
14+
@Bean("payment-orderPlacedListener") // a custom name to avoid collision
1515
OrderPlacedListener orderPlacedListener(CollectPayment collectPayment) {
1616
return new OrderPlacedListener(collectPayment);
1717
}

src/main/java/com/ttulka/ecommerce/billing/rest/PaymentController.java src/main/java/com/ttulka/ecommerce/billing/payment/rest/PaymentController.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
package com.ttulka.ecommerce.billing.rest;
1+
package com.ttulka.ecommerce.billing.payment.rest;
22

33
import java.util.List;
44
import java.util.Map;
55
import java.util.stream.Collectors;
66

7-
import com.ttulka.ecommerce.billing.FindPayments;
7+
import com.ttulka.ecommerce.billing.payment.FindPayments;
88

99
import org.springframework.web.bind.annotation.GetMapping;
1010
import org.springframework.web.bind.annotation.RequestMapping;

src/main/java/com/ttulka/ecommerce/catalogue/AddCartItem.java

-18
This file was deleted.

src/main/java/com/ttulka/ecommerce/catalogue/CartItemActions.java

-37
This file was deleted.

0 commit comments

Comments
 (0)