Repository Pattern in Go: Drivers and Portable Code
When writting software in terms of Domain-Driven Design (DDD), specifically in the context of Go, there’s a common interpretation of the Repository pattern which drives the implementation to something similar to the following code:
|
|
Now while this works, and it’s a good practice to use interfaces in general, this is a bit misleading as it makes it really difficult for UserRepository
to be portable in terms of infrastructure (think database layer).
All specific implementations of the repository will usually end up with some duplicate code (think things you need to do regardless of the internal storage engine being used), which is not ideal for obvious reasons.
For this particular reason, I generally like to define repositories as concrete types, and introduce a layer of abstraction (drivers) that deals with the specific details of each storage engine (pgsql, mysql, even docstore, etc):
|
|
This allows the repository to be totally agnostic in terms of the storage engine, making it really portable. For convenience, the repository can expose the same API as the driver or even extend it with some more features:
|
|
So, if your repository contains code which makes use of packages like sql/driver
, that’s the code you should move to a driver implementation.