Architecture – Clean Architecture Gateway layer depends on outer layer

Architectureclean-architecturedependency-inversion

Looking at the clean architecture layers and flow diagrams, and implemented it my self in my applications, I've always wondered which layer is supposed to contain the DB, or any 3rd Party service or SDK.

Looking at both of these images raises the question if there isn't violation in the outer layers.

enter image description here

enter image description here

I've imagined the layers division like this:

enter image description here

But this means that there is a violation of the dependancy rule. Since the gateway always knows about both the external service, and the application it self, the entities.

Is there a correct way to draw these layers? I've read a couple of resources asking this question, but didn't really get a full answers to what I need. For example: https://groups.google.com/g/clean-code-discussion/c/oUrgGi2r3Fk?pli=1, Doesn't repository pattern in clean architecture violate Dependency inversion principle?

I get it that the meaning of clean architecture is kept, and the inner layers, the entities and the use case, aren't affected by a change in the DB and the gateway, but was just wondering if maybe this is more accurate:

enter image description here

edit:

From the book:

Recall that we do not allow SQL in the use cases layer; instead, we use gateway interfaces that have appropriate methods. Those gateways are implemented by classes in the database layer.

So I guess this means that the data access is really in the most outer layer:

enter image description here

Maybe for this specific example, there is no real use for the interface adapters layer?

But also from the book about interface adapters layer:

Similarly, data is converted, in this layer, from the form most convenient for entities and use cases, to the form most convenient for whatever persistence framework is being used (i.e., the database). No code inward of this circle should know anything at all about the database. If the database is a SQL database, then all SQL should be restricted to this layer—and in particular to the parts of this layer that have to do with the database.

Also in this layer is any other adapter necessary to convert data from
some external form, such as an external service, to the internal form
used by the use cases and entities.

So it kinda contradicts that the data access is in the database layer, since this is what it does, converts from the DB, for example SQL rows, into the application's entities. Are these layers not really separated? I'm confused.

Best Answer

Frameworks and Drivers. The outermost layer is generally composed of frameworks and tools such as the Database, the Web Framework, etc. Generally you don’t write much code in this layer other than glue code that communicates to the next circle inwards.

This layer is where all the details go. The Web is a detail. The database is a detail. We keep these things on the outside where they can do little harm.

cleancoder.com - the clean architecture

So you do, in fact, write code in the blue layer. The the DB aware code goes where it says DB. Across the boundary though, what DB?

And that means, no, you do not run dependencies both ways across a boundary.

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.

Jacek Bilski - clean-code-discussion

So the gateway doesn't know it's talking to a DB. But it knows the needs of the application.

When I see "DB" in the outer ring of the clean architecture diagram I don't imagine the actual DB. I imagine the only DB aware code. After all, this is a diagram of an object graph. Not a system architecture.

Done this way, so long as whatever is plugged into your gateway can support its needs it doesn't matter if it's a DB, a file system, or system ram.