This is the fourth article of a 4 5 part series explaining Hexagonal Architecture and how to implement such an architecture using Spring Boot and TDD.

Part 1 - Introduction to Hexagonal Architecture and Key Concepts

Part 2 - Coding demo project and implementation of the API adaptor

Part 3 - Implementation of Domain Services

Part 4 - Implementation of MongoDB repository adaptor

Part 5 - Implementation of REST adaptor to an external data source

Part 2 of the video is live now:

Data Repository using MongoDB

Next we’ll implement the data repository required by domain service GetStockPositionService, as specified by the interface StockPositionsRepository.

Based on the expected behaviour of this interface, we specify two tests, the first for when the stock position is present, and the second for when it is not.

Notice that the interface and its tests are in the domain service package. This is because the behaviour of this interface is independent of the implementation.

However, to pass the tests, we need an implementation of this interface. Since the required behaviour is quite straightforward, we have chosen using Spring Data’s ReactiveMongoRepository for this implementation, though the tests StockPositionsRepositoryIntegrationTest applies even if we use some other implementation, for instance, using the ReactiveMongoTemplate or some other data storage technologies.

A few key points to note:

  1. In the domain repository interface (StockPositionsRepository) I have chosen to use the equivalent method names, e.g. findOneByUserAndSymbol, as specified by ReactiveMongoRepsotiory. While this simplifies the code, it does not impose a dependency on the implementation since we could just as easily implement the repository some other way.
  2. We could have extended StockPositionsRepository directly from ReactiveMongoRepository without using ReactiveMongoStockPositionRepository but that would mean that the domain interface, StockPositionsRepository, would now have knowledge about the implementation and be dependent on the adaptor implementation.
  3. Instead of using the domain model, StockPosition, directly as the document specification, StockPositionDocument which extends StockPosition is used as the document class in ReactiveMongoRepository. This, again, insulates the domain model from the implementation details, e.g. @Id ObjectId id .

It is debatable if such pedantry, especially points 2 & 3, simplifies or complicates the code, but I’ve chosen to use them here as illustrations of the options.

Back to Part 3

Continue to Part 5