At which level does Clean Architecture apply?
The other day, we had a discussion about where and how to apply the principles of clean architecture. This was very insightful. In this post, I would like to share them.
Read more: At which level does Clean Architecture apply?What does Clean Architecture mean?
The Clean Architecture concept has been defined multiple times over, with multiple names. A lot has been said about it; for example, this page gives a nice overview of the concept. If I had to summarize the concept, it would come down to two basic principles that need to be adhered to:
- All external dependencies are abstracted away by means of adaptation layers
- Dependencies may only point inwards, from adaptation layers towards the model. Adaptation layers do not depend on each other.
When these principles are applied, then it becomes possible to exchange dependencies without having to update the business rules. Business rules also become easily testable, which means that the system can be made very reliable.
Service oriented architecture
Another common concept is service oriented architecture, where the application is split up into a set of services that communicate with each other through defined interfaces. The most common variant of this concept is to implement services using REST APIs, so communication between services takes place using http. But if you design your application around services, is it possible to apply the Clean Architecture principles? And what is the scope of Clean Architecture? From the name it sounds that it should apply to the application as a whole, but is that even possible?
In my opinion, the answer sounds, like so often that it depends.
Clean Architecture and REST APIs
In order to see that, let’s first depict how services communicate. We take the example of two services called ServiceA and ServiceB. Some class in ServiceA wants something from ServiceB, so it sends a message. The global call can be depicted like this:
What’s missing here however, is that the call goes over intermediate layers. It needs to be transformed into a message which needs to be sent to the other service over http, after which it needs to be transformed back into a method call, perhaps in another programming language. If we included that in our diagram, then it looks more like this:
On the sender side, ServiceBProxy
represents a proxy that hides the complexity of sending the message to a REST api. For ServiceA, ServiceBProxy
acts as an adaptation layer to ServiceB. Likewise, for ServiceB, RESTApi
does something similar.
So there are clear adaptation layers, and the principles of Clean Architecture apply to each service, not to the application as a whole.
Services can be simpler
Does every service need to have a REST API? Not necessarily, this only depends on how it is being deployed and how it needs to be accessed. Working via REST is not a necessary requirement fora service oriented architecture. A service could as well be deployed as .NET assembly or Java jar.
But would the principles of Clean Architecture change by doing so? Let’s go back to our previous example, but now suppose that services are deployed as modules (assemblies, dlls, jars) in the same application process.
The class X
again calls a member of class Y
. However, this time, the call does not need to be wrapped, packaged, forwarded or unpacked, it is just a straight method call. So there is also no external dependency involved, hence, no adaptation is required. (This assumes that both services are under our control: we develop both services and can change their interfaces as we need.) This means that the application as a whole can be subject to the Clean Architecture scheme. After all, it is pointless to build adaptation layers for interfaces that are under our control.
When does Clean Architecture apply?
We’ve shown two examples of service oriented architectures, and discussed at which level the principles of Clean Architecture apply. The first example, which uses REST services, can only apply Clean Architecture on the service level. The second example, which uses libraries, can only meaningfully apply Clean Architecture on the application level. So, what is the criterion on which level to apply Clean Architecture?
This clearly depends on where dependencies like frameworks, UI or database are involved. Whenever you need to access one, you have to decouple. This happens at least when data leaves or enters the process’ memory, because you need external dependencies for that.