diff --git a/README.md b/README.md
index ac1e032..273b94c 100644
--- a/README.md
+++ b/README.md
@@ -15,11 +15,12 @@ Most of the information on how to design in this way are from the following book
To run this application you need to first run a
```cmd
-mvn clean install
+mvn clean
```
in the root directory of this project. This will download all required dependecies and bundle your
-project properly.
+project properly. It will also auto generate some mapping classes with
+the [mapstruct](https://mapstruct.org/) plugin.
The database for this application is a mongo db. You either need to have one running on your system,
or you can alternatively start the MongoDB in docker with the included docker-compose file.
@@ -50,7 +51,42 @@ way.
### Application architecture
-
+This application tries to follow the design princples as described in Clean Architecture. To achieve
+key characteristics of a good architecture (Single Responsibility, Flexibility, Testability, ... ),
+one very defining lession of Robert C. Martins book is that the business logik should be at the core
+of the system.
+
+
+
+This diagram shows where dependencies in a system should point to achieve this. How to implement
+this however, feels very abstract.
+
+Alistair Cockburn took this concept and
+definied [hexagonal architecture](https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)).
+Alternatively this style is also known as the ports and adapters architecture. Perhaps more fitting,
+but certainly not as exciting sounding as a hexagon.
+
+
+
+In the middle lives the **Domain**. This is where all the business logik is contained. Ideally this
+code is free of any framework specific annotations. This is especially great for unit testing your
+logik. No spring context, that has to boot, or any services that need to be mocked. Just plain
+normal Java, which is easy to understand and fast to execute.
+
+Ecapsulating these Domain models are the **Use Cases**. These represent the features that our
+application provides. They receive commands and query / write the data to the adapters.
+
+Between the Use Cases and the **Adapters** are the **Ports**. Especially the output ports are
+important to control the direction of dependencies. In Java these represent interfaces. The output
+adapters implement the output ports and therefore have to follow the contract, that the core of the
+application defines for them. The input adapters only interact with the input ports and never with
+the implementing serivces directly.
+
+This clear separation of concerns greatly increases flexibiliy. If you wanted to switch from an SQL
+to NoSQL DB, you'd just have to rewrite your Persistence Adapter, but the rest of the application
+should not be affected by your change.
+
+
### Advantages of separated models on each layer in this example
@@ -58,7 +94,10 @@ way.
the concern in what way to display the data to the client.
-- The customer can be persisted different from the domain models structure. The layout in this
- example has no benefit, but assume structuring your data in this way would give you a much needed
- performance boost. This way the concern on how to handle data persistence is independent from the
- business layer and can be handled by the persistence module.
+- The AddressType properties can be annotated with web specific annotiations to control
+ serialization, without cluttering the domain.
+
+
+- The customer can be persisted different from the domain models structure. This way the concern on
+ how to handle data persistence is independent from the business layer and can be handled by the
+ persistence module.
diff --git a/adapter/addressvalidation/src/main/java/de/strasser/peter/hexagonal/addressvalidation/AddressValidator.java b/adapter/addressvalidation/src/main/java/de/strasser/peter/hexagonal/addressvalidation/AddressValidator.java
index 1b82a15..06f4743 100644
--- a/adapter/addressvalidation/src/main/java/de/strasser/peter/hexagonal/addressvalidation/AddressValidator.java
+++ b/adapter/addressvalidation/src/main/java/de/strasser/peter/hexagonal/addressvalidation/AddressValidator.java
@@ -1,14 +1,14 @@
package de.strasser.peter.hexagonal.addressvalidation;
import de.strasser.peter.hexagonal.application.customer.domain.Address;
-import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorAdapter;
+import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorPort;
import de.strasser.peter.hexagonal.application.customer.port.out.commands.ValidateAddressCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
-class AddressValidator implements AddressValidatorAdapter {
+class AddressValidator implements AddressValidatorPort {
@Override
public Address validate(ValidateAddressCommand validateAddressCommand) throws InvalidAddressExc {
diff --git a/adapter/persistence/src/main/java/de/strasser/peter/hexagonal/persistence/CustomerDao.java b/adapter/persistence/src/main/java/de/strasser/peter/hexagonal/persistence/CustomerDao.java
index e964d0b..fe866bb 100644
--- a/adapter/persistence/src/main/java/de/strasser/peter/hexagonal/persistence/CustomerDao.java
+++ b/adapter/persistence/src/main/java/de/strasser/peter/hexagonal/persistence/CustomerDao.java
@@ -2,8 +2,8 @@ package de.strasser.peter.hexagonal.persistence;
import de.strasser.peter.hexagonal.application.customer.domain.Customer;
import de.strasser.peter.hexagonal.application.customer.port.in.QueryAllCustomersCRUD;
-import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerAdapter;
-import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerAdapter;
+import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerPort;
+import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerPort;
import de.strasser.peter.hexagonal.persistence.errors.CustomerDoesNotExistExc;
import de.strasser.peter.hexagonal.persistence.mapper.CustomerMapper;
import de.strasser.peter.hexagonal.persistence.model.CustomerEntity;
@@ -19,7 +19,7 @@ import java.util.List;
@Repository
@RequiredArgsConstructor
public class CustomerDao
- implements SaveCustomerAdapter, LoadCustomerAdapter, QueryAllCustomersCRUD {
+ implements SaveCustomerPort, LoadCustomerPort, QueryAllCustomersCRUD {
private final CustomerRepository customerRepository;
private final CustomerMapper customerMapper;
diff --git a/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/dto/response/AddressTypeResponse.java b/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/dto/response/AddressTypeResponse.java
new file mode 100644
index 0000000..f7c954a
--- /dev/null
+++ b/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/dto/response/AddressTypeResponse.java
@@ -0,0 +1,12 @@
+package de.strasser.peter.hexagonal.web.dto.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public enum AddressTypeResponse {
+ @JsonProperty("default")
+ DEFAULT,
+ @JsonProperty("shipping")
+ SHIPPING,
+ @JsonProperty("billing")
+ BILLING;
+}
diff --git a/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/dto/response/CustomerResponse.java b/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/dto/response/CustomerResponse.java
index 6a116a4..f437521 100644
--- a/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/dto/response/CustomerResponse.java
+++ b/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/dto/response/CustomerResponse.java
@@ -16,6 +16,6 @@ public class CustomerResponse {
private BigInteger id;
private String name;
private LocalDate birthday;
- private Map
addresses;
+ private Map addresses;
private int age;
}
diff --git a/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/mapper/AddressWebMapper.java b/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/mapper/AddressWebMapper.java
deleted file mode 100644
index b0e1baf..0000000
--- a/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/mapper/AddressWebMapper.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package de.strasser.peter.hexagonal.web.mapper;
-
-import de.strasser.peter.hexagonal.application.customer.domain.Address;
-import de.strasser.peter.hexagonal.web.dto.response.AddressResponse;
-import org.mapstruct.Mapper;
-
-import java.util.Map;
-
-@Mapper
-public interface AddressWebMapper {
- AddressResponse toResponse(Address address);
-
- Map toResponse(Map addresses);
-}
diff --git a/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/mapper/CustomerWebMapper.java b/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/mapper/CustomerWebMapper.java
index a8883f4..1568ad8 100644
--- a/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/mapper/CustomerWebMapper.java
+++ b/adapter/web/src/main/java/de/strasser/peter/hexagonal/web/mapper/CustomerWebMapper.java
@@ -1,13 +1,10 @@
package de.strasser.peter.hexagonal.web.mapper;
-import de.strasser.peter.hexagonal.application.customer.domain.Address;
import de.strasser.peter.hexagonal.application.customer.domain.Customer;
-import de.strasser.peter.hexagonal.web.dto.response.AddressResponse;
import de.strasser.peter.hexagonal.web.dto.response.CustomerResponse;
import org.mapstruct.Mapper;
import java.util.List;
-import java.util.Map;
@Mapper
public interface CustomerWebMapper {
diff --git a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/AddressValidatorAdapter.java b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/AddressValidatorPort.java
similarity index 87%
rename from application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/AddressValidatorAdapter.java
rename to application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/AddressValidatorPort.java
index f94f745..b154034 100644
--- a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/AddressValidatorAdapter.java
+++ b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/AddressValidatorPort.java
@@ -3,6 +3,6 @@ package de.strasser.peter.hexagonal.application.customer.port.out;
import de.strasser.peter.hexagonal.application.customer.domain.Address;
import de.strasser.peter.hexagonal.application.customer.port.out.commands.ValidateAddressCommand;
-public interface AddressValidatorAdapter {
+public interface AddressValidatorPort {
Address validate(ValidateAddressCommand validateAddressCommand);
}
diff --git a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/LoadCustomerAdapter.java b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/LoadCustomerPort.java
similarity index 84%
rename from application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/LoadCustomerAdapter.java
rename to application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/LoadCustomerPort.java
index 4f350c2..5520566 100644
--- a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/LoadCustomerAdapter.java
+++ b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/LoadCustomerPort.java
@@ -4,6 +4,6 @@ import de.strasser.peter.hexagonal.application.customer.domain.Customer;
import java.math.BigInteger;
-public interface LoadCustomerAdapter {
+public interface LoadCustomerPort {
Customer findById(BigInteger id);
}
diff --git a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/SaveCustomerAdapter.java b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/SaveCustomerPort.java
similarity index 82%
rename from application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/SaveCustomerAdapter.java
rename to application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/SaveCustomerPort.java
index 49b42a6..5d18922 100644
--- a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/SaveCustomerAdapter.java
+++ b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/port/out/SaveCustomerPort.java
@@ -2,6 +2,6 @@ package de.strasser.peter.hexagonal.application.customer.port.out;
import de.strasser.peter.hexagonal.application.customer.domain.Customer;
-public interface SaveCustomerAdapter {
+public interface SaveCustomerPort {
void upsert(Customer customer);
}
diff --git a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/AddressService.java b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/AddressService.java
index 17890d0..7e4fc7f 100644
--- a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/AddressService.java
+++ b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/AddressService.java
@@ -5,9 +5,9 @@ import de.strasser.peter.hexagonal.application.customer.domain.Customer;
import de.strasser.peter.hexagonal.application.customer.mapper.AddAddressMapper;
import de.strasser.peter.hexagonal.application.customer.port.in.AddAddressUseCase;
import de.strasser.peter.hexagonal.application.customer.port.in.commands.AddAddressCommand;
-import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorAdapter;
-import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerAdapter;
-import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerAdapter;
+import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorPort;
+import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerPort;
+import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerPort;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -22,9 +22,9 @@ import java.util.Map;
@Service
@RequiredArgsConstructor
class AddressService implements AddAddressUseCase {
- private final SaveCustomerAdapter saveCustomerAdapter;
- private final AddressValidatorAdapter addressValidatorAdapter;
- private final LoadCustomerAdapter loadCustomerAdapter;
+ private final SaveCustomerPort saveCustomerAdapter;
+ private final AddressValidatorPort addressValidatorAdapter;
+ private final LoadCustomerPort loadCustomerAdapter;
private final AddAddressMapper addAddressMapper;
@Override
diff --git a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerService.java b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerService.java
index b3f7163..87e22c6 100644
--- a/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerService.java
+++ b/application/src/main/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerService.java
@@ -3,7 +3,7 @@ package de.strasser.peter.hexagonal.application.customer.service;
import de.strasser.peter.hexagonal.application.customer.domain.Customer;
import de.strasser.peter.hexagonal.application.customer.port.in.RegisterCustomerUseCase;
import de.strasser.peter.hexagonal.application.customer.port.in.commands.RegisterCustomerCommand;
-import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerAdapter;
+import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerPort;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -16,7 +16,7 @@ import javax.validation.Valid;
@Validated
@RequiredArgsConstructor
class RegisterCustomerService implements RegisterCustomerUseCase {
- private final SaveCustomerAdapter saveUser;
+ private final SaveCustomerPort saveUser;
@Override
public void register(@Valid RegisterCustomerCommand registerCmd) {
diff --git a/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/AddressServiceTest.java b/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/AddressServiceTest.java
index 44d0693..bc76a32 100644
--- a/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/AddressServiceTest.java
+++ b/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/AddressServiceTest.java
@@ -4,9 +4,9 @@ import de.strasser.peter.hexagonal.application.customer.domain.Address;
import de.strasser.peter.hexagonal.application.customer.domain.Customer;
import de.strasser.peter.hexagonal.application.customer.mapper.AddAddressMapper;
import de.strasser.peter.hexagonal.application.customer.port.in.commands.AddAddressCommand;
-import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorAdapter;
-import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerAdapter;
-import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerAdapter;
+import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorPort;
+import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerPort;
+import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerPort;
import de.strasser.peter.hexagonal.application.customer.port.out.commands.ValidateAddressCommand;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -29,9 +29,9 @@ import static org.mockito.BDDMockito.then;
class AddressServiceTest {
@Autowired private AddressService sut;
- @MockBean private SaveCustomerAdapter saveCustomerAdapterMock;
- @MockBean private AddressValidatorAdapter addressValidatorAdapterMock;
- @MockBean private LoadCustomerAdapter loadCustomerAdapterMock;
+ @MockBean private SaveCustomerPort saveCustomerAdapterMock;
+ @MockBean private AddressValidatorPort addressValidatorAdapterMock;
+ @MockBean private LoadCustomerPort loadCustomerAdapterMock;
@SpyBean private AddAddressMapper addAddressMapperMock;
@Test
diff --git a/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerServiceTest.java b/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerServiceTest.java
index 22ed7bf..72817ed 100644
--- a/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerServiceTest.java
+++ b/application/src/test/java/de/strasser/peter/hexagonal/application/customer/service/RegisterCustomerServiceTest.java
@@ -2,9 +2,9 @@ package de.strasser.peter.hexagonal.application.customer.service;
import de.strasser.peter.hexagonal.application.customer.mapper.AddAddressMapper;
import de.strasser.peter.hexagonal.application.customer.port.in.commands.RegisterCustomerCommand;
-import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorAdapter;
-import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerAdapter;
-import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerAdapter;
+import de.strasser.peter.hexagonal.application.customer.port.out.AddressValidatorPort;
+import de.strasser.peter.hexagonal.application.customer.port.out.LoadCustomerPort;
+import de.strasser.peter.hexagonal.application.customer.port.out.SaveCustomerPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -25,11 +25,11 @@ class RegisterCustomerServiceTest {
private RegisterCustomerService sut;
@MockBean
- private SaveCustomerAdapter saveCustomerAdapterMock;
+ private SaveCustomerPort saveCustomerAdapterMock;
@MockBean
- private AddressValidatorAdapter addressValidatorAdapterMock;
+ private AddressValidatorPort addressValidatorAdapterMock;
@MockBean
- private LoadCustomerAdapter loadCustomerAdapterMock;
+ private LoadCustomerPort loadCustomerAdapterMock;
@MockBean
private AddAddressMapper addAddressMapperMock;
diff --git a/documentation/Hexagonal.png b/documentation/Hexagonal.png
new file mode 100644
index 0000000..a66d185
Binary files /dev/null and b/documentation/Hexagonal.png differ
diff --git a/documentation/circles.png b/documentation/circles.png
new file mode 100644
index 0000000..895e169
Binary files /dev/null and b/documentation/circles.png differ
diff --git a/documentation/dependencies.png b/documentation/dependencies.png
new file mode 100644
index 0000000..e1b6356
Binary files /dev/null and b/documentation/dependencies.png differ
diff --git a/documentation/dependency_diagram.drawio b/documentation/dependency_diagram.drawio
index 9ac4e86..a167d52 100644
--- a/documentation/dependency_diagram.drawio
+++ b/documentation/dependency_diagram.drawio
@@ -1 +1 @@
-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
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/documentation/dependency_diagram.jpg b/documentation/dependency_diagram.jpg
deleted file mode 100644
index f76e2e4..0000000
Binary files a/documentation/dependency_diagram.jpg and /dev/null differ