For various reasons, I've been reading a lot of late on Hexagonal Architecture / Ports and Adapters. On the face of it, this seems really neat.
Basically, you define an inner domain, with the domain models, interfaces for all of the ports that the domain depends on - the driven ports, and interfaces for the ports that the domain exposes - the driving ports. The domain then also has a service that implements the driving ports on terms of the driven ports.
The benefit here is that anything depending on the Driving ports needs know nothing about the internals, and anything implementing the Driven ports can be plugged in. This means, for example, we can plug the domain into a web server, a command line app or an Android app with no business logic changes. It also means we can plug in a Postgres database, or a DynamoDB database with no changes to the business logic.
This all sounds really good. But does it work?
My very first thought was about changing database technology, and the fact that different databases do different things. And specifically about text searching.
If I decide to use Postgres then it has full text searching built in, so I only need one port and one adapter. If I decide to use DynamoDB then it does not have support for text searching, so I would need a second port for a full text engine, and an adapter for CloudSearch.
The problem here is that the choice of infrastructure defines the ports, and this is exactly Not the point.
The alternative is that we implement the DataStore and the TextSearch ports for Postgres, but have the TextSearch just do nothing when indexing documents. Except this is a waste of effort. Worse, it seems reasonable that the TextSearch port returns the ID of the matching records for the DataStore port to fetch, but if they're both the same database then this is a performance sink - it's two queries when one would suffice.
So, unless someone can enlighten me (please!), it seems that this architecture is potentially very tied to the infrastructure decisions after all.