Microservices simplified: Distributed processes
Microservices simplified: Distributed processes

Microservices simplified: Distributed processes

In this article I'd like to discuss from a birds eye view, how business processes, distributed across multiple microservices can be simplified using an abstract model. This is part of a series of articles about how microservice architecture can be applied in a domain centric way without constantly dealing with technical aspects.

If you haven't done it yet, I recommend checking my other articles in this series.

First of all let me clarify what I mean by process in software design. A process in my interpretation is a series of small tasks a software program can execute, in a specific order given by an algorithm. It has one entry point which initiates the execution and one or more outputs, communicating the result of the process outside of it.

Running and terminating a process is relatively straightforward, from the programmer point of view it's basically implementing an algorithm which is modeling the business domain within the limits of the chosen framework and programming language.

The most interesting part is initiating the process which can be done in many ways especially in a distributed ecosystem such as microservices. So let's focus on how triggering a process can be generalized in a technology agnostic way, but still, giving the possibility to model a large variety of scenarios such as Http requests, Servicebus messages, time triggered jobs or file uploads.

I think the most suitable candidate for the job is Event Driven Architecture, which when applied means that every interaction from inside and outside of the system is modeled by starting with an event and executing the domain process in the form of one or multiple event handlers. I'm not the one inventing this, there are many excellent articles about the benefits of combining event-driven and microservices architectures together.

So lets see a flow of creating an order and updating the inventory in a microservice architecture where an order and an inventory service are involved.

No alt text provided for this image

Because we talk about Event Driven Architecture, we should clarify a bit what an event is.

The Event, in its definition, contains the domain model encapsulating all the input (output of the publisher) parameters for the processes that it triggers. One or many flows can be triggered by an event depending on how many event handlers are. This means that the event handler is always the entry point of a flow.

The next example presents the handling of an event, published by another microservice:

No alt text provided for this image

Subscribing to the event is done by a generic event subscriber responsible to materialize the event and resolving the event handlers. This offers a great opportunity to set contextual information (creator user, tenant, language etc.) sent by the event publisher. For more details see my article about inter service communication.

What we already have is providing the ground to implement business processes that are triggered from the inside of the microservice ecosystem, but software solutions are rarely closed systems, they have to also handle external triggers (e.g. browser requests) which have to be authorized and validated before they are executed. For this purpose we used two special type of event: Commands and Queries.

Commands, besides holding a domain model, also contain in their definition an authorization resource in the form of a string which is understood by the authorization service. They always have only one command handler and one or more command validators.

An example of a command and command handler for creating an order and publishing the OrderRegistered event:

No alt text provided for this image

And the command validator:

No alt text provided for this image

A Query is basically a simpler command used to model flows that doesn't involve a state change in the system (see Http Get ) therefore they don't need any validation and their query handler returns domain objects as the query result.

No alt text provided for this image

The orchestration of authorization, validation (command only) and execution of the handler is done by the command dispatcher, following the principles of the Command design pattern. Do not confuse this with Command Query Responsibility Segregation

And a look of how all the MVC controllers should look like when handling Http requests with the command pattern:

No alt text provided for this image

So why this trouble with commands and events and handlers, instead of implementing the domain logic directly in the controller?

To understand the benefit of this abstraction we have to put into perspective what we actually have.

We have the event subscriber and the command dispatcher which wraps every piece of logic that we will implement in the future, and this allows us to implement cross cutting concerns like exception handling, logging, data validation, authorization and custom DI and apply them in one place.

We also now have a way of extending the system with functional flows by creating events/commands/queries and handlers, focusing on business requirements without further dealing with how the flow was triggered or the existence of cross cutting concerns.

No alt text provided for this image

I hope with the above examples I managed to demonstrate how, using abstraction of the process triggers and execution made it possible to implement new functional features with no technical interference, focusing on domain requirements without dealing with the technical aspects we already incorporated.

要查看或添加评论,请登录

Tibi Nagy的更多文章

  • Why Certifications Still Matter

    Why Certifications Still Matter

    I’m thrilled to share that I’ve just earned the Microsoft AI-102: Designing and Implementing an Azure AI Solution…

  • Unit tests simplified: how to bring order in chaos

    Unit tests simplified: how to bring order in chaos

    Despite the title of this article which is too dramatic, because probably there is no chaos in the way most of us are…

  • Microservices simplified: Exception handling

    Microservices simplified: Exception handling

    In this article I'd like to discuss how exception handling can be implemented at application level without the need of…

  • Microservices simplified: Logging

    Microservices simplified: Logging

    In this article I'd like to discuss how logging can be implemented in a generic way without polluting the domain logic…

  • Microservices simplified: Configuration management

    Microservices simplified: Configuration management

    In this article I'd like to discuss how accessing application level configuration can be simplified using a convention…

  • Microservices simplified: Caching

    Microservices simplified: Caching

    In this article I'd like to discuss how caching can be simplified by abstraction in a way in which it extends the…

  • Microservices simplified: Inter service communication

    Microservices simplified: Inter service communication

    In this article I'd like to discuss how service-to-service communication can be simplified by abstracting the…

  • Microservices simplified: An overview

    Microservices simplified: An overview

    In this series of articles I'd like to share ways in which microservice based solutions can be simplified and built in…

  • Thought about programing: TODO or not TODO?

    Thought about programing: TODO or not TODO?

    In this post I share my thoughts about a common phenomenon I noticed in many projects and according to the way I'm…

    3 条评论

社区洞察

其他会员也浏览了