JSON-RPC? Take the tricky REST

JSON-RPC? Take the tricky REST

I'm sure the headline elicited 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 will allow you to look at the choice of the data exchange paradigm in your projects from a new angle.

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

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

The point is that in RPC it is possible to call several procedures at once in one request. For example, create a user, add an avatar to him, and subscribe him to some topics in the same request. Just one request, and how many benefits!

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

JSON-RPC? Take the tricky REST

Note that the first request in the case of REST must return a user ID in order to make 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 even called HighLoad, should not be built like that. Their infrastructure must meet the criteria for high availability and load. And the picture is changing.

JSON-RPC? Take the tricky REST

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

It is enough to enter into the script not two requests for enrichment, but, say, five or ten ... and the answer to the question “who wins now?” becomes invisible.

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

JSON-RPC? Take the tricky REST

See how the infrastructure on RPC has noticeably “recovered” in order to meet the requirements 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 find them in the documentation at HTTP. For RPC, POST requests are used, which are not considered idempotent, that is, repeated repetition of the same POST requests may return different results (for example, after each comment is sent, another copy of this comment will appear) (source).

Consequently, RPC is not able to make efficient use of infrastructure caches. This leads to the fact that you have to “import” soft caches. The diagram shows Redis in this role. The soft cache, in turn, requires an additional code layer and noticeable changes in the architecture from the developer.

Let's now calculate how many requests REST and RPC "gave birth" in the infrastructure under consideration?

Inquiries
Inbox
to backend
to DBMS
to soft cache (Redis)
TOTAL

REST
1 / 32 *
1
1
0
3 / 35

RPC
32
32
1
31
96

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

In comparison with the first scheme, the difference is striking. Now the benefit of REST becomes obvious. But I suggest not to stop there. Developed infrastructure includes CDN. Often, it also solves the issue of countering DDoS and DoS attacks. We get:

JSON-RPC? Take the tricky REST

Here for RPC everything becomes quite deplorable. RPC is simply unable to delegate work to a CDN load. We can only hope for systems to counter attacks.

Is it possible to end there? And again, no. HTTP methods, as mentioned above, have their own “magic”. And it's not for nothing that the GET method is totally used on the Internet. Note that this method is able to access a piece of content, is able to set conditions that infrastructure elements can interpret before passing control to your code, and so on. All this allows you to create flexible, manageable infrastructures that can handle really large requests. And in RPC this method is ... ignored.

So why is the myth that batch requests (RPC) are faster so persistent? 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 willing to show his weakness.

The choice of REST or RPC is not a volitional choice of an individual in a project. This choice must meet the requirements of the project. If the project is able to squeeze all that it really can out of REST, and it really needs it, then REST is a great choice.

But if in order to get all the REST profits, you need to hire devops for the project to quickly scale the infrastructure, admins to manage the infrastructure, an architect to design all layers of the WEB service ... and the project, at the same time, sells three packs of margarine a day ... I would stop at RPC, tk. this protocol is more utilitarian. It does not require deep knowledge of the operation of caches and infrastructure, but will focus the developer on simple and understandable calls to the procedures he needs. Business will be happy.

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

This property of RPC is a definite plus, because it is easy to keep the database in a consistent state. But with REST it gets more and more difficult. Requests may come inconsistently to different backend nodes.

This "flaw" of REST is the reverse side of its advantage described above - the ability to efficiently use all infrastructure resources. If the infrastructure is poorly designed, and even more so if the project architecture 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 consider a case: we create a user, enrich his profile with some description and send him an SMS with a secret to complete registration. Those. three calls in one batch request.

JSON-RPC? Take the tricky REST

Let's consider a diagram. It presents an infrastructure with elements of high availability. There are two independent communication channels with SMS gateways. But… what do we see? When sending an SMS, an 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 cancelled. The client receives an error.

The next attempt is a lottery. Either the request will again fall on the same node and again return an error, 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 there was no profit.

Okay, let's imagine that we've tensed up (!) and thought about the option when the request can be partially executed successfully. And the rest, we will again try to execute after some time interval (What? Decides the front?). But the lottery remained the same. The request to send an SMS with a 50/50 chance will fail again.

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

JSON-RPC? Take the tricky REST

REST again uses the "magic" of HTTP, but now with response codes. When 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, which successfully processes the request. Those. the client receives the expected result, and the infrastructure confirms its high title of “highly accessible”. The user is happy.

And again, that's not all. The balancer did not just receive a 503 response code. According to the standard, it is desirable to provide this code with the “Retry-After” header when responding. The title makes it clear to the balancer that this node should not be disturbed on this route during the specified time. And the next requests to send SMS will be sent immediately to the 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 consistency in the database. 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 definitely a plus. If the project involves high availability with high load, REST looks like a more correct, albeit more complex solution.

REST Entry Threshold Lower

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

So why do many people think that REST will be simpler? My personal opinion is that this apparent simplicity comes from the REST manifests themselves. Those. REST is not a protocol, but a concept… REST doesn't have a standard, there are some guidelines… REST is no more complicated than HTTP. Seeming freedom and anarchy attracts "free artists".

Undoubtedly, REST is no more complicated than HTTP. But HTTP itself is a well thought out protocol that has proven its worth 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 dumb JSON-RPC? Or is it still tricky REST? You decide.

I sincerely hope that I have not wasted your time.

Source: habr.com

Add a comment