Microservices Communication!
Omar Ismail
Senior Software Engineer @ Digitinary | Java 8 Certified? | Spring & Spring Boot?????? | AWS? | Microservices ?? | RESTFul Apis & Integrations ?? FinTech ?? | Open Banking ?? | Digital Payments and Transformation??
Thanks To: https://medium.com/design-microservices-architecture-with-patterns/microservices-communications-f319f8d76b71
Microservice architecture is all about communication. How should services communicate in any given business scenario? Should they call each other synchronously? Or should they communicate via asynchronous messaging? As always, this is not a black-or-white decision. This article discusses some prominent communication patterns.
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 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:
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:
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.
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:
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.
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:
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.
14+ Experience In Development|Java 1.8|Microservices|Spring Boot|RESTful Services|Spring Data JPA|Hibernate|Spring Security|Caching|Linux|Team-Handling|Agile Methodology|Maven Prompt-Engineering, ChatCPT, GitHub-Copilot.
1 年very nice article
Engineering @ Securiti | Distributed Systems | GoLang | Java | Spring Boot | Quarkus
1 年You've used event bus and messaging queues interchangeably in this article and that's sort of confusing because their functionality is different.