Microservices Communications

Mehmet Ozkaya
17 min readSep 7, 2021

--

In this article, we’re going to learn Microservices Communications. We will learn definitions, communication types and how they can use in microservices architectures on e-commerce domain.

By the end of the article, you will learn Microservices Sync and Async Communications with patterns and practices. We will discuss RESTful APIs, gRPC and Message Broker systems.

Step by Step Design Architectures w/ Course

I have just published a new course — Design Microservices Architecture with Patterns & Principles.

In this course, we’re going to learn how to Design Microservices Architecture with using Design Patterns, Principles and the Best Practices. We will start with designing Monolithic to Event-Driven Microservices step by step and together using the right architecture design patterns and techniques.

Microservices Communications

When we are talking about Monolithic applications, we said that the communication in Monolithic applications are inter-process communication. So that means it is working on single process that invoke one to another by using method calls. You just create class and call the method inside of target module. All running the same process.

This communication gives is very simple but at the same time components are highly coupled with each other and hard to separate and scale independently.

One of the biggest challenge when moving to microservices-based application is changing the communication mechanism. Because microservices are distributed and microservices communicate with each other by inter-service communication on network level. Each microservice has its own instance and process. Therefore, services must interact using an inter-service communication protocols like HTTP, gRPC or message brokers AMQP protocol.

Since microservices are complex structure into independently developed and deployed services, we should be careful when considering communication types and manage them into design phases.

Before we design our microservices communications, we should understand about communication styles, it is possible to classify them in two axes. The first step is to define communication protocol is synchronous or asynchronous.

Microservices Communication Types — Sync or Async Communication

We are going to learn Microservices Communication types — Synchronous Asynchronous Communication.

Client and services communicate with each other with many different types of communication. Mainly, those types of communications can be classified in two axes.

Synchronous and Asynchronous

Lets start to talk about Synchronous communication.

What is Synchronous communication ?

Basically, we can say that Synchronous communication is using HTTP or gRPC protocol for returning sync response. The client sends a request and waits for a response from the service. So that means client code block their thread, until the response reach from the server.

The synchronous communication protocols can be HTTP or HTTPS.
In synchronous communication, the client sends a request with using http protocols and waits for a response from the service.

So that means the client call the server and block client their operations.
The client code will continue its task when it receives the HTTP server response. So this operation called Synchronous communication. It has pros and cons that we should consider when we pick this way.

Another communication type is Asynchronous communication.

What is Asynchronous communication ?

Basically, In Asynchronous communication, the client sends a request but it doesn’t wait for a response from the service. So the key point here is that, the client should not have blocked a thread while waiting for a response.

The most popular protocol for this Asynchronous communications is AMQP (Advanced Message Queuing Protocol). So with using AMQP protocols, the client sends the message with using message broker systems like Kafka and RabbitMQ queue. The message producer usually does not wait for a response. This message consume from the subscriber systems in async way, and no one waiting for response suddenly.

An asynchronous communication also divided by 2 according to implementation. An asynchronous systems can be implemented in a one-to-one(queue) mode or one-to-many (topic) mode.

In a one-to-one(queue) implementation there is a single producer and single receiver. But in one-to-many (topic) implementation has Multiple receivers. Each request can be processed by zero to multiple receivers. one-to-many (topic) communications must be asynchronous.

So we will see this communication with the publish/subscribe mechanism used in patterns like Event-driven microservices architecture in the upcoming articles. Basically an event-bus or message broker system is publishing events between multiple microservices, and communication provide with subscribing these events in an async way.

Kafka and RabbitMQ is the best tools for this operations.

As you can see that we have understand Microservices Communication types — Sync or Async Communication, And microservice-based application will often use a combination of these 2 communication styles. So we will also design our e-commerce architecture with using both communication types.

But before that, lets elaborate the Synchronous communication and underlying mechanism.

Microservices Synchronous Communication and Practices

As we said before, In synchronous communication, the client sends a request with using http protocols and waits for a response from the service. The synchronous communication protocols can be HTTP or HTTPS.

But how we can design and exposing APIs with HTTP protocols for our microservices ? we should focus on that point.

When we are using a synchronous request/response-based communication type, HTTP protocols and REST approaches are the most common way to use to design APIs, especially if we’re exposing APIs to the outside of the microservice cluster.

If we’re communicating between services internally within our microservices cluster, we might also use binary format communication mechanisms like gRPC. gRPC is one of the best way to communicate for internal microservice communication, we will see gRPC in the upcoming sections.

E-Commerce Service Communications

Lets check our e-commerce architecture design.

As you can see that now these lines representing sync communication. And these communication will be HTTP based RESTful APIs which will return to JSON objects. But if there is required to communicate internal microservices, its good to choose gRPC binary protocols in order to be fastest as posible.

We use different protocols for client call and the internal communication even both type is sync communication. Because client request is good to be REST in order to see payloads explicitly, But backend communication can be sacrifice to see payloads instead of pick velocity of response time. gRPC much faster than rest.

So we can say that, if we prefer to communicate with synchronous communication, we have several options those are; HTTP protocols and REST approaches. gRPC binary format communications.

So lets elaborate these 2 approaches.

Designing HTTP based RESTful APIs for Microservices

In synchronous communication, when making request/response communication, we should use REST when designing our APIs. Its also called Restful APIs. REST approach is following the HTTP protocol, and implementing HTTP verbs like GET, POST, and PUT.

REST is the most commonly used architectural communication approach when creating APIs for our microservices. For implementing REST services, we have several options for example using Java and Sprint Boot framework or using C# with ASP.NET Core Web API services.

Anyway, we should focus on how to design our APIs for microservices.

Good API design is very important in a microservices architecture, because communication with data transfers happens through messages or API calls.

Designed APIs should be efficient and not to be chatty communications. Because In microservices architecture, services are designed for working independently, APIs must have well-defined documented and versioning, so updates don’t break other services.

There are 2 type of APIs when designing sync communication in microservices architecture.

1- Public APIs which is APIs calls from the client applications.
2- Backend APIs which is used for inter-service communication between backend microservices.

For Public APIs, should be align with client request. Clients can be web browser or mobile application requests. So that means the public API should use RESTful APIs over HTTP protocol. So RESTful APIs should use JSON payloads for request-response, this will easy to check payloads and easy agreement with clients.

For the backend APIs, We need to consider network performance instead of easy readable JSON payloads. Inter-service communication can result in a lot of network traffic. For that reason, serialization speed and payload size become more important. So for the backend APIs, These protocols support binary serialization should implement. The protocol alternatives is using gRPC or other binary protocols are mandatory.

Let me compare the REST and gRPC protocols,

REST is using HTTP protocol, and request-response structured JSON objects. API interfaces design based on HTTP verbs like GET-PUT-POST and DELETE.

gRPC is basically Remote Procedure Call, that basically invoke external system method over the binary network protocols. Payloads are not readable but its faster that REST APIs.

So lets elaborate these 2 approaches.

  • RESTful API Design over HTTP using JSON
  • gRPC binary protocol API Design

RESTful API design for Microservices

In synchronous communication, when making request/response communication, we should use REST when designing our APIs. Its also called Restful APIs. REST approach is following the HTTP protocol, and implementing HTTP verbs like GET, POST, and PUT.

RESTful services are widely used in modern Web architectures. It is pretty lightweight, extensible and simple easy develop services. We will start with REST definition and after that talk about RESTful Apis and how to design RESTFul Apis.

What is REST ?

REST (Representational State Transfer) is a service structure that enables easy and fast communication between client and server. Roy Fielding introduced and developed REST in his doctoral thesis in 2000. It was developed as an alternative to SOAP and WSDL based Web services. REST runs on HTTP.

Compared to alternative structures, it is faster and more efficient in sending and receiving data with more basic and minimum content. REST allows applications to communicate with each other by carrying JSON data between the client and server.

Features of REST

When we look at the constraints of the REST architecture, we come across six items:

  • Stateless
  • Uniform Interface
  • Cacheable
  • Client-Server
  • Layered System
  • Code on Demand

I am not going to deep insight of these features but you can consider these are the characteristics of REST services.

What is RESTful APIs?

Web services that use REST architecture are called RESTful services. RESTful systems generally communicate over HTTP protocol with HTTP methods (GET, POST, PUT, DELETE etc.) used by Web Browsers to transfer pages.

Richardson Maturity Model

In 2008, Leonard Richardson proposed the Richardson Maturity Model for web APIs:

Level 0: Define one URI, and all operations are POST requests to this URI.
Level 1: Create separate URIs for individual resources.
Level 2: Use HTTP methods to define operations on resources.
Level 3: Use hypermedia

These are the levels of calculating maturity of REST APIs.

Lets understand the HTTP Methods which basically performs http operation over the APIs.

HTTP Methods

GET :
The GET method is used to fetch the resource specified in the URI. There is no body in this request. It’s just the header. It is used for data listing and display operations. Requests made with GET must be secure. When data is sent with GET, it is sent in the address bar.

POST
We use the POST method to create a new resource on the server. We send the request in order to run the controller resources and to send the form inputs. Since we will send data for all these operations, we also send the body when using the POST method. It is used to add data and update existing data. Data is not displayed in the address bar, unlike the GET method.

PUT
The PUT method has a usage area similar to the POST method. A resource is sent with the body and if the URI points to an existing resource, that resource is updated. It is used to update data. Different from the POST method, the result is the same even if the request is repeated multiple times.

DELETE
As the name suggests, it is the request sent to delete the resource specified in the URI. It is only used to delete the relevant resource and never be accessed again.

PATCH : Used to update a single piece of data.

How we can design Restful APIs for microservices ?

We should focus on the business entities that we expose APIs for our application. So that means we should organize our resources according to business entities and expose them properly via APIs.

Lets think about our e-commerce application, the primary entities might be customers and orders. When creating an order, we basically send HTTP POST request with contains customer and order detail information's. And return back to HTTP response that including 200 OK success response.

So how we can handle this kind of Restful API ? The best practice is the resource URIs should be based on nouns (the resource) and not verbs.

For example :
https://eshop.com/orders // Correct

https://eshop.com/create-order // Wrong

So now lets think about the e-commerce application and our Customer and Order entities, resources.

So if we design http methods, it should be on this table:

https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design

Since we are using http protocol, You can find Different Resource Urls are indicating with http verbs like get-put-post and delete.

See the table we have /customers main resource. and we can filter by adding /1 and /orders by following REST principles.

Microservices RESTful API Design

If we talk about the microservices design on APIs you can see the image;

In a microservices architecture, microservices don’t share the same code base and don’t share data stores. Instead of that, they communicate through APIs for data operations.

If we look at the image, the Shopping Cart service requests information about a customer from the Customer service. The Customer service retrieve data with using Repository classes and return Customer entity model as a JSON object in an HTTP response. So this provide to isolation of services.

What is gRPC ?

gRPC (gRPC Remote Procedure Calls) is an open source remote procedure call (RPC) system initially developed at Google. gRPC is a framework to efficiently connect services and build distributed systems.

It is focused on high performance and uses the HTTP/2 protocol to transport binary messages. It is relies on the Protocol Buffers language to define service contracts. Protocol Buffers, also known as Protobuf, allow you to define the interface to be used in service to service communication regardless of the programming language.

It generates cross-platform client and server bindings for many languages. Most common usage scenarios include connecting services in microservices style architecture and connect mobile devices, browser clients to backend services. The gRPC framework allows developers to create services that can communicate with each other efficiently and independently from their preferred programming language.

Once you define a contract with Protobuf, this contract can be used by each service to automatically generate the code that sets up the communication infrastructure. This feature simplifies the creation of service interaction and, together with high performance, makes gRPC the ideal framework for creating microservices.

How gRPC works ?

In GRPC, a client application can directly call a method on a server application on a different machine like it were a local object, making it easy for you to build distributed applications and services.

As with many RPC systems, gRPC is based on the idea of defining a service that specifies methods that can be called remotely with their parameters and return types. On the server side, the server implements this interface and runs a gRPC server to handle client calls. On the client side, the client has a stub that provides the same methods as the server.

gRPC clients and servers can work and talk to each other in a different of environments, from servers to your own desktop applications, and that can be written in any language that gRPC supports. For example, you can easily create a gRPC server in Java or C# with clients in Go, Python or Ruby.

Working with Protocol Buffers

gRPC uses Protocol Buffers by Default. Protocol Buffers are Google’s open source mechanism for serializing structured data.

When working with protocol buffers, the first step is to define the structure of the data you want to serialize in a proto file: this is an ordinary text file with the extension .proto. The protocol buffer data is structured as messages where each message is a small logical information record containing a series of name-value pairs called fields.

Once you’ve determined your data structures, you use the protocol buffer compiler protocol to create data access classes in the languages you prefer from your protocol definition.

You can find the whole language guide into google’s official documentation of protocol buffer language. Let me add the link as below.
https://developers.google.com/protocol-buffers/docs/overview

gRPC Method Types — RPC life cycles

gRPC lets you define four kinds of service method:

Unary RPCs where the client sends a single request to the server and returns a single response back, just like a normal function call.

Server streaming RPCs where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. gRPC guarantees message ordering within an individual RPC call.

Client streaming RPCs where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them and return its response. Again gRPC guarantees message ordering within an individual RPC call.

Bidirectional streaming RPCs where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes.

Advantages of gRPC

General advantages of gRPC:

  • Using HTTP / 2

These differences of HTTP / 2 provide 30–40% more performance. In addition, since gRPC uses binary serialization, it needs both more performance and less bandwidth than json serialization.

  • Higher performance and less bandwidth usage than json with binary serialization
  • Supporting a wide audience with multi-language / platform support
  • Open Source and the powerful community behind it
  • Supports Bi-directional Streaming operations
  • Support SSL / TLS usage
  • Supports many Authentication methods

gRPC vs REST

gRPC is in an advantage position against REST-based APIs that have become popular in recent years. Because of the protobuf format, messages take up less space and therefore communication is faster.

Unlike REST, gRPC works on a contract file basis, similar to SOAP.

Encoding and Decoding part of gRPC requests takes place on the client machine. That’s why the JSON encode / decode you make for REST apis on your machine is not a problem for you here.

You do not need to serialize (serialization / deserialization) for type conversions between different languages because your data type is clear on the contract and the code for your target language is generated from there.

gRPC usage of Microservices Communication

gRPC is primarily used with backend services.

But also gRPC using for the following scenarios:

  • Synchronous backend microservice-to-microservice communication where an immediate response is required to continue processing.
  • Polyglot environments that need to support mixed programming platforms.
  • Low latency and high throughput communication where performance is critical.
  • Point-to-point real-time communication — gRPC can push messages in real time without polling and has excellent support for bi-directional streaming.
  • Network constrained environments — binary gRPC messages are always smaller than an equivalent text-based JSON message.

Example of gRPC in Microservices Communication

Think about that we have a Web-Marketing API Gateway and this will forward to request to Shopping Aggregator Microservice.

This Shopping Aggregator Microservice receives a single request from a client, dispatches it to various microservices, aggregates the results, and sends them back to the requesting client. Such operations typically require synchronous communication as to produce an immediate response.

In this example, backend calls from the Aggregator are performed using gRPC. gRPC communication requires both client and server components. You can see that Shopping Aggregator implements a gRPC client. The client makes synchronous gRPC calls to backend microservices, this backend microservices are implement a gRPC server. As you can see that, The gRPC endpoints must be configured for the HTTP/2 protocol that is required for gRPC communication.

In microservices world, most of communication use asynchronous communication patterns but some operations require direct calls. gRPC should be the primary choice for direct synchronous communication between microservices. Its high-performance communication protocol, based on HTTP/2 and protocol buffers, make it a perfect choice.

Drawbacks of the direct client-to-microservices communication

We will compare the API gateway pattern and the Direct client-to-microservice communication. We have understand how to design Restful APIS for our microservices architecture. So for every microservices should exposes a set of fine-grained endpoints to communicate each other.

In this view, each microservice has a public endpoint, and when we open public endpoint from our microservices, it has lots of drawbacks that we should consider.

When you build large and complex microservice-based applications for example, when handling dozens of microservices, than these direct-to-microservices communication can make problems.

The client try to handle multiple calls to microservice endpoints but this is not manageable. Also if we think that new microservices can be add our application, its really hard to manage those from the client application.

If we expand these problems; It can cause to lots of requests to the backend services and it can create possible chatty communications. This approach increases latency and complexity on the UI side. Ideally, responses should be aggregated in the server side.

Also implementing security and cross-cutting concerns like security and authorization for every microservice is not to good way of implementations. These cross-cutting concerns should handle in centralized place that can be in internal cluster. Also if there is a long-running apis that need to work on async communications, its hard to implement event-driven publish-subscribe model with message brokers from the client applications.

So these are the drawbacks of the direct client-to-microservices communication. Instead of that we should use API Gateways between client and internal microservices.

API Gateways can handle that Cross-cutting concerns like authorization
so instead of writing every microservices, authorization can handle in centralized API gateways and sent to internal microservices.

Also API gateway manage routing to internal microservices and able to aggreate several microservice request in 1 response.

So What’s Next ?

See that UI and MS communication are direct, and it seems hard to manage communications. We now we should focus on microservices communications with applying API GW pattern and evolving these architecture step by step.

Step by Step Design Architectures w/ Course

I have just published a new course — Design Microservices Architecture with Patterns & Principles.

In this course, we’re going to learn how to Design Microservices Architecture with using Design Patterns, Principles and the Best Practices. We will start with designing Monolithic to Event-Driven Microservices step by step and together using the right architecture design patterns and techniques.

References :

https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design
https://denizirgin.com/rest-ve-restful-web-servis-kavram%C4%B1-30bc4400b9e0
https://wmaraci.com/nedir/rest-api
https://halilozel1903.medium.com/rest-ve-restful-nedir-f6c8596eb38a

--

--

Mehmet Ozkaya

Software Architect | Udemy Instructor | AWS Community Builder | Cloud-Native and Serverless Event-driven Microservices https://github.com/mehmetozkaya