Clean Architecture: Gateways (DB, external services) have to violate the Dependency Rule

2,238 views
Skip to first unread message

Pavel Gatilov

unread,
Nov 17, 2016, 9:36:19 AM11/17/16
to Clean Code Discussion
The Clean Architecture article says that the Dependency Rule is the core principle and must be followed on all layers. When applied to Gateways and DB+External Services, it implies that the Gateways should not know DB/Service details. I am not sure I understand it correctly. Seems like it's not possible, because the layer has to have code that knows about specific DB engine, tables, Service wsdl and whatever. It has to contains specific SQL queries or service calls. Even if it is possible to invert the dependency on the DB using event subscription features for some DB engines, it's hard to expect that an external service vendor would implement pub/sub for the sake of another app's clean architecture.

At the same time, it doesn't seem to be that much important to follow the Dependency Rule strictly when we are on the outer circles. The goal is to isolate the domain and application logic, while DB/gateway separation seems less important.

So, is it correct that the Dependency Rule is expected to be violated between the 2 outer layers, or am I getting it all wrong, and Gateway is not about actual SQL queries, but rather about supporting multiple data sources?

Thank you.

Marko Avlijas

unread,
Nov 18, 2016, 12:12:08 PM11/18/16
to Clean Code Discussion
What you'd do is use adapter design pattern.
Do you remember how Uncle Bob divides your application into main section (low  level details) and application section (high level policy).

Your application (high level policy part) would just call CRUD methods  on  an  abstract class which wouldn't know anything about database. Lets call this class Persistence.
You'd write a class that derives from it implements it and call it MySqlPersistence  or PostgresPersistence and that  class would deal  with low level details.

You can  also check out what ActiveRecord is doing (rails).

Marko Avlijas

unread,
Nov 18, 2016, 12:29:39 PM11/18/16
to Clean Code Discussion
But you really wouldn't have Persistance class. What he did in fitnesse which is software about wiki pages, he had a class WikiPage which had business logic. He derived from that class classes called FileWikiPage and MySqlWikiPage. So if you have Employee class you can derive  from it MySqlEmployee or PostgresEmployee.

Jacek Bilski

unread,
Nov 19, 2016, 6:49:33 AM11/19/16
to clean-code...@googlegroups.com
I'd put it in a different way. Think of your gateway as a contract (like
Java interface). User of this contract, something sitting in more inner
ring is defining what is needed. And on contract level there should be
nothing that would require a specific technology or any implementation
details. Of course, there needs to be an implementation of this
contract, where you can put all the details like those DB structure or
SQL queries.

The idea is, and we're currently doing this at work, that we're cutting
our monolith into smaller products. So far we're getting all information
from one DB, so we created contracts and their implementations going
directly to DB. Bus as soon as someone prepares a RESTful service that
is providing the same information, we're replacing only implementation
of the contract, nothing in our inner circles needs to change.

So we're not violating dependency rule, there's no need. And the whole
idea of clean, port and adapter or hexagonal architectures are exactly
the same, one part defines a contract and doesn't care how it is
implemented or how many implementations are there, and the other part(s)
implement/fulfil those contracts using technologies of their choosing.

--
Pozdrawiam / Best regards / Mit freundlichen Grüßen

Jacek Bilski

DarkTrick

unread,
Jul 17, 2022, 9:47:02 AM7/17/22
to Clean Code Discussion
> You'd write a class that derives from it implements it and call it MySqlPersistence  or PostgresPersistence and that  class would deal  with low level details.

Thinking of the DBMS as the framework layer in the bottom, `MySqlPersistence` will ultimately sit above that layer and have a dependency down to it. Simply because your code is completely different system than you DBMS. Therefore: Principle is violated.
You would need to implement MySqlPersistence within the DBMS (perhaps some kind of stored procedures) in order to not violate the principle.
Reply all
Reply to author
Forward
0 new messages