Understanding Microservices using AbhiShop App
By: Abhi Kempanna
Tags: Dotnet Core, Microservices, Distributed Systems, Microservice Architecture, Monolithic

This is the third article in this series.

Link to the previous article: AbhiShop App using Monolithic Approach

Roadmap towards Microservices

Microservices is an architectural approach of functionally decomposing applications into units of services. To understand what is meant by functional decomposition, we need to look into the concept of scale cubing firstly. There are three different ways of scale cube: x-axis scaling, z-axis scaling, and y-axis scaling. Figure 3.1 depicts x-axis scaling; this type of scaling improves the availability & capacity of the application by passing the request using a load balancing algorithm.

Figure 3.1 X-axis scaling

Z-axis scaling is depicted in the below Figure 3.2; decision is taken based upon the request attribute, which is sent to the router. Z-axis scaling also improves application availability.

Figure 3.2 Z-axis scaling

But both x-axis & z-axis scaling fail to solve the problem of application complexity & expanding development.

Y-axis scaling is the solution, and it functionally decomposes an application into services.

Figure 3.3 Y-axis scaling

Microservices way of design utilizes the concept of y-axis scaling. In the Figure above, the AbhiShop monolith app is visualized in terms of functional decomposition, identified functional parameters such as Inventory, User, Cart, Orders. How are functional parameters identified? One rule of thumb that has been followed while breaking the Monolith is to identify functions within the application, which can possess meaning individually.

For instance, Inventory management would involve implementation, addition of inventory items. User login/registration would involve details involving user registration, identity tokens so on. Further, Cart management may deal with just the mechanism of the shopping cart for users & Order management may comprise of orders, payments. In the y-axis scaling world, by functionally decomposing the application, we are increasing the scalability & maintenance qualities.

There are various obstacles we can think of when decomposing an application into services. Maintaining data consistency among services could be a challenge; the Presence of God classes may prevent decomposition. God classes are classes that are used throughout an application. Let us get into the various concepts involved in microservices further.

Each service in micro-architecture is organized around business capabilities rather than technical concerns. There might be a significant question that might arise with respect to how will we achieve communication between the microservices? An asynchronous message would be the answer. Asynchronous messaging could be of two types: one to one or one to many. One to one might be asynchronous request/response one-way notifications. One too many is the publish/subscribe model.

When to migrate to microservices? When the application has outgrown its architecture. In the AbhiShop app, if the development team faces regular issues with respect to scaling resulting in slower delivery & buggy software. Better maintainability, testability, and deployability of the application will accelerate development. For microservices, keep the idea of “smart endpoints, dumb pipes” in mind. Dumb pipes include message broker or direct service to service communication using lightweight protocols like REST; REST stands for Representational state transfer.

Before understanding the concept of REST, it is important to know about a concept known has Simple object access protocol (SOAP). SOAP is a protocol, whereas REST is an architectural style. REST uses standard HTTP (Hypertext transfer protocol), and it has better performance and reliability. We might have the question which might be the best suitable way for web service communication in the microservices world?

The choice depends upon the level of freedom with respect to coupling the selected protocol would provide between client and server implementation. SOAP involves tightly coupled, a rigid contract between the client and server, whereas REST provides a loosely coupled environment, which is what we need for services development.

Technology decisions taken towards Microservices approach

Microservices defined as small autonomous services that specialize in one thing and designed around business domain capabilities. It is relatively easy to isolate changes and failures in this approach. Scaling the application is better; usage of lightweight communication protocols such as asynchronous communication is some of the benefits of this design.

With respect to database architecture, each microservice owns its database. Other microservices cannot connect directly to the database of a different microservice. They could use service interfaces like API’s, events to connect. Let’s take AbhiShop app example; we can have an inventory database specific to inventory management, token database specific to user identity, and registration in this approach when compared to our Monolith app wherein we just had one database.

Scalability has been one of the major takeaways of microservices approach. Microservices pair well with containers that bring in the benefit of scalability. Dockers are one way to realize containerization in our application. If the AbhiShop application is containerized in docker if it runs in my machine, then it will run in any other machine as well. By definition, the docker makes images of the container. However, Docker containers are not similar to virtual machines. Docker containers share the operating system kernel with other containers.

Let’s think in the scenario of AbhiShop app, how can containers be effective? As mentioned previously, once functional decomposition of the application is accomplished by breaking the monolith as Inventory, Carts, User identity, and having individual databases. We have components that show the ability to act as small autonomous services, and this gives us a platform to use containers. Docker file will give information about each service. Every service will have a docker file. How will they be connected? They will be connected using docker- compose, which acts as a connector for the various docker files within the application.

When using docker, the development team created a service, packages the service & dependencies into a container image — an image defined as a static representation of the service, its configuration & dependencies. In the AbhiShop app, the services within have individual images, let’s say. These images instantiated to create a container that will run on the Docker host. The images stored in a registry, which will act as a storage of images and needed during deployment in production. The figure below depicts schematically certain concepts involved in docker.

Figure 3.4 Docker

Application architectures based on microservices will have cross-platform needs. .NET core is suitable for containers & microservices when compared to .NET framework. Strong dependency on the Windows platform is one of the major disadvantages of not using .NET framework for microservices development. Lightweight nature and modularity of .NET core makes it perfect. The major advantage of the microservice model is this allows technologies to mix around service boundaries. The cross-platform nature of microservices makes .NET core ideal.

Figure 3.5 depicts various different communication ways in microservices. Communication could be broadly divided into two categories: First axis and the second axis.

Figure 3.5 Ways of communication in microservices

In the first axis, we have a synchronous and asynchronous way of communication. In synchronous mode, when a request sent, the response is expected in the same thread. Whereas on the asynchronous way when a request sent, the response not expected immediately, it can be back on another thread. In the second axis, we have a single receiver and multiple receivers’type. Publisher/subscriber is an example of multiple receivers where the request processed by more than one receiver.

We may be faced with this question, how to go ahead with development when we need data from another microservice? Eventual consistency is the answer. A microservice needs data that is owned by another microservice. The data has to be transferred to the service asking for using asynchronous event-driven communication instead of synchronous communication.

Asynchronous event-driven communication is the concept wherein a microservice publishes an integration event when a change occurs within its domain, and additional microservices subscribe to these events so they can receive them asynchronously. In the AbhiShop app scenario, let us say in the Inventory management, the price of an inventory item is modified (Figure 3.6). This price change has to now reflect in cart management microservice, order management microservice. That could only be achieved if inventory able to publish the changes as events that are subscribed by cart management and order management services asynchronously.

Figure 3.6 Async Event Driven Communication

Entity framework core can be a way to access data in .NET Core. We can inject DB Context into the developed API controllers. EFCore implemented in the microservices part of our app.

API gateway is a concept discussed when microservices development is in the picture. Since in the series further, we will be having a single client application (Web MVC), so API gateway not implemented, but it is important to understand the concept. When we build large complex microservice-based applications with multiple client apps, it would be beneficial to consider an API gateway.

API gateway provides a single point of entry, it is similar to the facade design pattern in object-oriented programming, but in this case, it is part of distributed systems. API Gateway acts in between the client apps & the microservices. Has the ability to act as a reverse proxy, routing requests from clients to services, providing features like authentication. In our AbhiShop app, suppose we get a requirement that our application should serve multiple client apps, the addition being a mobile app. In this scenario, when multiple client apps are involved, it would be beneficial to implement the feature of API gateways.

We need to keep one important aspect clear when dealing with API gateways. API gateways can sometimes act like a monolithic aggregator or orchestrator. That may potentially violate microservices architecture by coupling all microservices. API gateways should be strictly designed based on business boundaries and client apps.

With these design decisions as the backbone idea, let us get into the design and development of the AbhiShop app using microservices architecture.

Figure 3.7 Microservices System Design

Figure 3.7 above depicts a visualization of AbhiShop as a microservices model. Will be functionally decomposing the application into Inventory, Token, Cart, Order service. Each microservice with its own database. The client-facing app will be the ASPNET Core MVC (Model View Controller) Client app. Further, each of the services will be containerized using docker.

In the next article in this series will be getting into the development part of the microservices in the AbhiShop App.