Implementation of a MongoDB repository adaptor (Hexagonal Architecture with Spring Boot — Part 4)
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:
- In the domain repository interface (
StockPositionsRepository
) I have chosen to use the equivalent method names, e.g.findOneByUserAndSymbol
, as specified byReactiveMongoRepsotiory
. 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. - We could have extended
StockPositionsRepository
directly fromReactiveMongoRepository
without usingReactiveMongoStockPositionRepository
but that would mean that the domain interface,StockPositionsRepository
, would now have knowledge about the implementation and be dependent on the adaptor implementation. - Instead of using the domain model,
StockPosition
, directly as the document specification,StockPositionDocument
which extendsStockPosition
is used as the document class inReactiveMongoRepository
. 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.