I’m working with AWS SDK and was wondering if it is worth abstracting over it. By abstracting i mean:
- Creating a library where i would define interfaces for IQueue, IFileStorage, …
- Creating implementations for those interfaces like SqsQueue for IQueue or S3Storage for IFileStorage
I’m considering two cases:
-
A project realised according to DDD, developed in the Ports & Adapters architecture. I would think that in the Application layer this would be correct approach.
-
A big data project aimed at populating a data warehouse. No complex domain model here. I’m not sure about the benefits here. Automated tests would be more readable and clear. Maybe mocking would be easier with less complex interfaces. This would come at a price of a lot of boiler plate being created in the interfaces library.
What would be the best approach in both those cases?
2
Answers
As you already pointed out: it is a trade-off decision. When focusing on portability or simply the cost of changing such a dependency in future, abstracting the dependency (AWS SDK) away is a good idea. The downside is additional code but maybe also performance.
Nevertheless, in most cases it is probably better to have your application (at least its core) decoupled from the "hosting environment/framework".
I doubt that these interfaces will give you a good abstraction, because it’s hard to decouple an application at this level. I don’t want to say that it is not possible, but more about that later…
What I mean is that we often introduce interfaces like IQueue and we just repeating the API, that for example AWS has. Such interfaces will not help you to switch to another provider, because they are usually structural tightly coupled. Nevertheless those interfaces will still help you with unit tests.
I would either define interfaces on the buisiness level. E.g. an interface
DomainEventPublisher
and e.g. an event likeOrderPlacedEvent
. The implementation can then send it to an SqsQueue. Those interfaces are usually better when it comes to mobillity, because they are on the business and not the technical level. Instead of the IFileStorage I would use e.g. anInvoiceRepository
.It is possible to define an interface that is a queue or a file storage abstraction, but it is also a lot more effort to find a good abstraction that makes it portable. You must carefully decide which queue aspects you put in it and which ones are not very common between different queues. Those interfaces are portable, but they usually do not provide a lot of features. Because those features usually differ from queue to queue provider.