Unit 12.04: Keeping the driver out of your services
Queries belong in one directory, and the service should not know they exist.
Router, service, repository
Three layers and what each may import.
The code states the rule for each.
LAYERS = [
("router", "no SQL, no driver imports"),
("service", "no SQL, no driver imports -- calls the repository"),
("repository", "the ONLY place queries are written"),
]
for layer, rule in LAYERS:
print(f"{layer:12} {rule}")
print("""
Two things this buys. The service can be tested with a fake repository -- a
dictionary -- so its logic is exercised without a database at all.
And changing storage is a change in one directory. A query written inline in a
handler spreads the driver through the codebase, and every one of those places
has to be found when the storage changes.
""")
The service can be tested with a fake repository - a dictionary - so its logic is exercised with no database at all. That is what keeps the logic tests fast enough to run continuously.
And changing storage becomes a change in one directory. A query written inline in a handler spreads the driver through the codebase, and every one of those places has to be found later.
The mistake this prevents
The mistake is writing one quick query in a handler because the repository does not have that method yet. It is the first of many, and by then the boundary exists only in the documentation.
Takeaway
Confine queries to the repository layer. The service is then testable with a dictionary, and a storage change touches one directory.
