Architecture for event-driven applications
Architectural paradigms have shifted dramatically with the transition from monolithic applications that share code to more message-based approaches. when three tier architecture While virtual was the go-to architecture for monolithic applications, it proved to be a less than ideal fit for applications that are event driven.
The shift from monolithic applications has been going on for a few years now, and industry leaders such as Spotify outlines its shift to Cloud Native And how they deal with billions of incidents every day without interruption.
Perhaps an application that streams music to your device isn’t the first one that comes to mind when you think of event-driven architecture – and that’s exactly what makes it so powerful.
You can define almost anything as an event. send an email? transfer money? Grant access to some super secret computer system? It doesn’t matter what you’re implementing; It’s just an event and a handler at the core of the application.
Over the years, a number of architectural patterns have emerged that deal with this complexity in various ways. Three notable ones are Onion Architecture, Hexagonal Architecture, and Clean Architecture.
All three are equally different. They all focus on moving the infrastructure to the outer layers and are very well suited for event-driven applications.
They all deserve their own articles, but we’ll dive specifically into Clean Architecture in this.
clean architecture Originally from Robert C. defined by martin And, like Onion and Hexagonal Architecture, emphasizes on externalizing infrastructure details like databases, messaging, etc.
Identifying infrastructure components and moving them to external layers of the application ensures that they do not accidentally mix with business rules or other application code, creating a dependency.
In a clean architecture, dependencies always point inwards. If we look at the diagram below, it would mean that it would be fine for
Web components for reference
Controllers component, but not the other way around.
Since inner layers can never know about any details of outer layers (or their existence, for that matter), interfaces are used to expose functionality across boundaries. Data Transfer Objects (DTOs) are often used to move data across layers.
Let’s say you have an entity, and that entity will need a repository to manage its storage needs. We can declare the repository’s interface at the entities level in the diagram above as it deals with entities, and it doesn’t know anything about the particular storage mechanism we’ll be using – nor care about.
It just retrieves entities from some storage and puts them back later. That’s all I know. Interface represents functionality. This interface can be used by any external layer.
When implementing the interface, we must decide on our storage medium. Let’s assume we are using a SQL database to store our entities.
We can’t possibly add the Repository implementation to the Entity layer because that would mean that the Entity layer is now completely biased towards the SQL database, and that’s the whole thing we want to avoid.
The storage we are using is for supporting the application in a way. It does not provide direct value to the business, and is not an application feature or use case. This is a strong indicator that it is probably part of the infrastructure of the application.
Therefore, implementing the Repository interface declared at the entity layer would be in the outermost infrastructure layer. This ensures that the implementation details of how entities are stored do not pollute the entities or the application itself.
In the previous section, we touched on the entities and infrastructure layers. Entities represent business goods, customer and their relevant data, orders ready for shipment, etc. They are more likely to change because of internal changes than external ones.
Our infrastructure layer deals with the implementation details. How do we store items, what service do we use to send email, etc.?
The application layer, or use case layer, deals with business logic and directs the flow of entities. If you are designing a flight booking system, and have a business rule that states that you can overbook a flight, then the application layer is where you would define that rule.
This is the layer where the cosmic magic happens. If something changes in day-to-day operations, or a new feature has to be added to the system, it could mean changes in the application layer.
Although it is not explicitly specified by the architecture, this layer is often structured using Command – Query Separation, which deals neatly with events. Each event is either a command or a query, and is handled by a command or event handler. Each of these message interactions can represent a single use case or feature.
Another interesting aspect that defines clean architecture is that it encourages what is called Chilla Architecture,
The basic premise of a Screaming architecture is simple: each application must shout what it does. It’s not what language it is written in, what framework does it use, but what functionality does the application enable?
Depending on your programming language, this may be implemented differently. But it usually comes in the form of a very recognizable organization of code, as shown below:
Without seeing anything in the project, you can probably tell that you’re looking at a sort of event booking system.
Due to the layered approach, applications that implement a clean architecture are easily testable. You can be certain that your tests aren’t obstructed by obscure implementation details like a specific database or some over-the-top mailing service.
This means that the tests can implement in-memory database based on SQL database. Don’t need mailing services? Just make fun of them and forget about it.
Often, I’ve seen clean architecture applications focus on testing their use cases rather than more traditional unit testing. In end-to-end testing of your application layer, you can ensure that the core functionality of your application works as expected without testing each line separately.
We’ve just dipped our toes into the clean architecture and what it offers. If I have to summarize, clean architecture is a testable, event-centric and layered architecture which is a very good go-to architecture if you don’t have a clear idea of what you are building.
Because of the lack of layering and dependencies, you have a good variety of flexibility. For example, you can start your application in a monolithic fashion. When you have a better idea of what the outside world looks like, you can split your events, handlers, and entities into microservices without any pain. You can even take it up a notch and have domain driven if you want.
If you are interested in this topic, I recommend “Clean Architecture by Robert C. Martin(the same one who wrote the blog post I linked).
You can also take a look at an example project I wrote clear ticket, It is a relatively small implementation of an event ticketing system implementing a clean architecture.
Thanks for reading, and I hope I’ve managed to pique your interest!
#Dive #clean #architecture #Architecture #eventdriven #Martin #Cerruti #September