JSON-RPC? Take the tricky REST







I am sure that the headline caused a healthy reaction - “Well, it started again ...” But let me grab your attention for 5-10 minutes, and I will try not to deceive expectations.







The structure of the article will be as follows: a stereotypical statement is taken and the “nature” of the emergence of this stereotype is revealed. I hope this allows you to look at the choice of the data exchange paradigm in your projects from a new angle.







In order to make it clear what RPC is, I propose to consider the JSON-RPC 2.0 standard. There is no clarity with REST. And it should not be. All you need to know about REST - it is indistinguishable from HTTP .







RPC requests are faster and more efficient because they allow batch requests.



The point is that in RPC it is possible to make a call of several procedures in one request. For example, create a user, add an avatar to him and in the same request sign him on some topics. Just one request, and how much good!







Indeed, if you only have one backend node, this will seem faster with a batch request. Because three REST requests will require three times as many resources from one node to establish connections.













Please note that the first request in the case of REST should return the user ID for subsequent requests. Which also negatively affects the overall result.







But such infrastructures can be found, perhaps, in in-house solutions and Enterprise. As a last resort, in small WEB projects. But full-fledged WEB solutions, and also called HighLoad, should not be built like this. Their infrastructure must meet the criteria of high availability and load. And the picture is changing.













Green indicates infrastructure activity channels under the same scenario. Notice how RPC behaves now. The request uses the infrastructure only one shoulder from the balancer to the backend. While REST still loses in the first request, but makes up for lost time using the entire infrastructure.







It is enough to enter in the script not two enrichment requests, but, say, five or ten ... and the answer to the question “who wins now?” Becomes unobvious.







I propose to look even broader at the problem. The diagram shows how infrastructure channels are used, but the infrastructure is not limited to channels. An important component of highly loaded infrastructure are caches. Let's get some user artifact now. Repeatedly. Say 32 times.













See how the infrastructure on the RPC has visibly “recovered” to meet the demands of high load. The thing is that REST uses the full power of the HTTP protocol, unlike RPC. In the above diagram, this power is realized through the request method - GET.







HTTP methods, among other things, have caching strategies. You can get to know them in the documentation for HTTP . For RPC, POST requests are used that are not considered idempotent, that is, repeated repetition of the same POST requests can return different results (for example, after each comment is sent, another copy of this comment will appear) ( source ).







Consequently, RPCs are not able to use infrastructure caches efficiently. This leads to the fact that you have to “import” software caches. The diagram shows Redis in this role. The soft cache, in turn, requires an additional code layer and significant changes in the architecture from the developer.







Let’s now calculate how many requests “gave birth” to REST and RPC in the considered infrastructure?







Inquiries Inbox to backend to DBMS to soft cache (Redis) TOTAL
REST 1/32 * one one 0 3/35
Rpc 32 32 one 31 96


[*] in the best case (if the local cache is used) 1 request (one!), in the worst 32 incoming requests.







In comparison with the first scheme, the difference is striking. Now the REST win is becoming apparent. But I propose not to stop there. Developed infrastructure includes CDN. Often, he also solves the issue of countering DDoS and DoS attacks. We get:













Here for RPC, everything becomes very deplorable. The RPC is simply not able to delegate work with a CDN load. One can only rely on systems to counter attacks.







Is it possible to end this? And again, no. HTTP methods, as mentioned above, have their own “magic”. And for good reason the GET method is totally used on the Internet. Please note that this method is able to access part of the content, is able to set conditions that can interpret the infrastructure elements before transferring control to your code, etc. All this allows you to create flexible, managed infrastructures that can digest really large flows of requests. And in RPC, this method ... is ignored.







So why is the myth so persistent that batch requests (RPC) are faster? Personally, it seems to me that most projects simply do not reach such a level of development when REST is able to show its strength. Moreover, in small projects, he is more likely to show his weakness.







The choice of REST or RPC is not a voluntary choice of an individual in the project. This choice should meet the requirements of the project. If the project is able to squeeze out from REST everything that it really can, and it really is necessary, then REST will be an excellent choice.







But if in order to get all the REST profits, you will need to hire devops to quickly scale the infrastructure, administrators to manage the infrastructure, an architect to design all layers of the WEB service ... and the project will sell three packs of margarine per day ... I I would stop at RPC, because this protocol is more utilitarian. It will not require in-depth knowledge of the operation of caches and infrastructure, but will focus the developer on simple and understandable calls to the procedures he needs. The business will be pleased.







RPC requests are more reliable because they can execute batch requests in a single transaction



This property of RPC is a definite plus, as easy to keep the database in a consistent state. But with REST, everything is more complicated. Requests may arrive inconsistently on different backend nodes.







This “drawback” of REST is the flip side of its advantages described above - the ability to effectively use all infrastructure resources. If the infrastructure is poorly designed, and even more so if the architecture of the project and the database in particular are poorly designed, then this is really a big pain.







But are batch requests as reliable as they seem? Let's look at the case: create a user, enrich his profile with some description and send him an SMS with a secret to complete the registration. Those. three calls in one batch request.













Let's consider the scheme. It presents the infrastructure with elements of high availability. There are two independent communication channels with SMS gateways. But ... what do we see? When sending SMS, error 503 occurs - the service is temporarily unavailable. Because sending SMS is packaged in a batch request, then the entire request should be rolled back. Actions in the DBMS are canceled. The client receives an error.







The next attempt is a lottery. Either the request will again go to the same node and return an error again, or you will be lucky and it will be executed. But the main thing is that at least once our infrastructure has already worked in vain. There was a load, but no profit.







Well, let's imagine that we tensed up (!) And thought out the option when the request could be partially completed successfully. And the remainder, we will again try to fulfill after some time interval (Which? Decides the front?). But the lottery remained. A request to send an SMS with a probability of 50/50 will fail again.







Agree, on the client’s side, the service does not seem as reliable as we would like ... but what about REST?













REST uses HTTP magic again, but now with response codes. If a 503 error occurs on the SMS gateway, the backend broadcasts this error to the balancer. The balancer receiving this error, and without breaking the connection with the client, sends the request to another node that successfully processes the request. Those. the client receives the expected result, and the infrastructure confirms its high rank of “highly accessible”. The user is happy.







And again, this is not all. The balancer didn’t just receive a response code 503. It is advisable to provide this code with the “Retry-After” header when responding. The header makes it clear to the balancer that you should not disturb this node on this route for a specified time. And the following SMS sending requests will be sent immediately to a node that has no problems with the SMS gateway.







As we can see, the reliability of JSON-RPC is overrated. Indeed, it is easier to organize database consistency. But the victim, in this case, will be the reliability of the system as a whole.







The conclusion is largely similar to the previous one. When the infrastructure is simple, the obviousness of JSON-RPC is undoubtedly its plus. If a project involves high availability with a high load, REST looks like a more accurate, albeit more complex, solution.







REST entry threshold below



I think that the above analysis, debunking the established stereotypes about RPC, clearly showed that the threshold for entering REST is undoubtedly higher than in RPC. This is due to the need for a deep understanding of HTTP, as well as the need to have sufficient knowledge about the existing infrastructure elements that can and should be used in WEB projects.







So why do many people think that REST will be easier? My personal opinion is that this apparent simplicity comes from the REST manifests themselves. Those. REST is not a protocol, but a concept ... REST has no standard, there are some recommendations ... REST is not more complicated than HTTP. Apparent freedom and anarchy attracts “free artists”.







Undoubtedly, REST is no more complicated than HTTP. But HTTP itself is a well-designed protocol that has been proven for decades. If there is no deep understanding of HTTP itself, then REST cannot be judged.







But about RPC - you can. It is enough to take its specification. So do you need a dumb JSON-RPC ? Or is it cunning REST? You decide.







I sincerely hope that I did not waste your time in vain.








All Articles