From the course: Building Java Microservices with gRPC

Inter-service communication

From the course: Building Java Microservices with gRPC

Start my 1-month free trial

Inter-service communication

- [Instructor] Let us do a recap of inter-service communication. Modern software applications no longer reside in a monolith today. This big block of code, which is the monolith, is divided into smaller units, which are independent and autonomous. They can be efficiently maintained and they are highly scalable. Let us take a look at a typical micro-services system. A user service, an order service, and a payment service. These three services manage the shopping orders for their customers. When a request comes into the system via a client, let's say a web browser or a mobile app, the entire process starts with user service. The user can log in and then can either retrieve orders or create new orders. For this, the user service will talk to the order service. When an order needs to be checked out, the order service will talk to the payment service to facilitate the payment of the checkout. The payment service can then in turn talk to the user service to retrieve any user specific information to complete the payment. These three services can talk to a data store, like a database, or can even communicate with an external service for any other cross-cutting concern that the entire system requires. So essentially, these three services will collaborate with each other by passing messages between them. These messages can be passed in a synchronous or in an asynchronous fashion. Asynchronous message passing is when you place messages in logical cues so that the services can pick them up in the background and carry on with their further processing. Let us see how the inter-service communication has evolved over the last few years. We started with RPC, Remote Procedural Call. In this, the client invokes a procedure on the server site in a different address space. As if the client was trying to call the function locally. RPC uses TCP protocol which hinders inter operability. RPCs are overwhelmingly complex to implement. It induces a certain amount of vulnerability because you're trying to connect to a different system in a different address space. And hence also incurs a lot of costs. Popular implementations of RPC are Java RMI, CORBA, etcetera. Owing to limitations of RPC, we switched to a new standard, SOAP, Simple Object Access Protocol. This specification was designed and promoted by a number of big enterprises. SOAP is based on the services oriented architecture, or as we say, the SOA principle. In this, the client and the server exchange data in the form of XML. And since it is XML, it can be implemented across platforms and systems, which are completely different from each other. SOAP works over both DCP and HTTP protocol. SOAP is prevalent in a lot of legacy services today because there are a few limitations. XML is difficult to deal with. It has a strict set of rules that you need to know to work with it. Which means even the smallest string message transmitted between the client and the server amounts to a heavy payload which eventually leads to performance issues. Agility of distributed applications are a problem to implement with the SOAP specification. Hence, we moved on to REST. REST is a specification in which you define the methods of a service. And a service then is a bunch of resources, each with a unique identifier, URL. REST works only with HTTP protocol. REST is the de facto standard for implementing microservices today. However, it also comes in with a few limitations. Firstly, REST has text-based message calls. The client always produces data in a binary format. It has to be converted to text to get transmitted over the HTTP protocol. That is because HTTP understands only text. When the response is received on the server side, the server has to convert that message from text again to binary. So this conversion from binary to text and text to binary amounts to performance overhead. REST only exposes CRUD, or CRUD behaviors, create, read, update, delete. And these behaviors has got a set name of methods that you need to define in your service The names of those methods are, get ghost, put delete, patch, etcetera. Which means if you need to give a custom name to your method, you will always have to work around these set names in order to expose your specific API. This becomes a little cumbersome in the long run. REST does not define strict interface types. Even when you have open API or swagger specifications, it is not tightly bound with the underlying architecture or the message in protocol. The service and the type definitions are sometimes not even written completely before the implementation gets started. At times, the developers even just look over the wire for the data format and code the functionality accordingly. This results in incompatibility, inconsistency and a lot of runtime problems when the calls are made. So then what do you do in order to overcome these limitations of REST? The answer to that question is, let's switch to the gRPC framework.

Contents