DEV Community

Radix
Radix

Posted on

JSON-RPC vs REST for distributed platform APIs

What is REST?

You have probably read about REST a thousand times, but here we go once again:

Let’s start by saying that REST stands for Representational State Transfer, and essentially refers to a style of web architecture that governs the behavior of both client and server.

An API that adheres to the principles of REST doesn’t require the client to know anything about the structure of the API. Rather, the server needs to provide whatever information the client needs to interact with the service. A form in HTML is a clear example of this: the server specifies the location of the resource and the required fields. The browser doesn’t know in advance where to submit the information neither what information to submit. Both forms of information are entirely supplied by the server [1].

REST APIs are everywhere, and distributed ledger technologies are no exception. This is a general example for getting the hash of the latest block added to the Bitcoin blockchain using the Bitcoin Rest API:

// Request
curl -X GET https://blockchain.info/q/latesthash
// Result
0000000000000000002d9c2483cd87685ef41e7b8d1ca718206120e9b1bfee43

So, what about JSON-RPC?

RPC stands for Remote Procedure Call and is a protocol that one program can use to request a service from a program located in another computer on a network without having to understand the network’s details. RPC uses the client-server model. The requesting program is a client and the service providing program is the server. Like a regular or local procedure call, an RPC is a synchronous operation requiring the requesting program to be suspended until the results of the remote procedure are returned. Nevertheless, the use of lightweight processes or threads that share the same address space allows multiple RPCs to be executed concurrently [2][3].

The concept of RPC has been around the software development world for over half a century (yea, time flies), but despite that fact, it is still not as widely known as would be expected for something that enduring.

That being said, it is actually not so surprising, taking into account that most of the current software is web-based, and REST was actually designed with the web-first mindset. When REST came out, RPC APIs were still using XML, and this was problematic. In XML, many attributes are just strings and it’s necessary to ensure the datatypes by adding a metadata layer describing things such as which fields are of which type.

Nowadays, many known decentralised platforms use JSON-RPC based APIs: Ethereum, Ripple and Bitcoin among others.

Here we can see an example of how to use Ethereum’s JSON-RPC API to get the balance of a given account:

// Request
curl -X POST —data ‘{
  “jsonrpc”: “2.0”,
  “method”: “eth_getBalance”,
  “params”: [ "0x407d73d8a49eeb85d32cf465507dd71d507100c1" , "latest" ],
  "id": 1
}’
// Response
{
  "jsonrpc": "2.0",
  "result": "0x0234c8a3397aab58" // 158972490234375000,
  "id": 1
}

But why JSON-RPC for distributed ledger technologies APIs? [5][6]

Agnostic to the protocol

It is hard to emphasise this point enough. If I had to select only one reason why I would choose JSON-RPC over REST is the fact that with JSON-RPC we can have APIs out-of-the-box with which the clients can communicate using any protocol. This has the extra benefit of allowing us to improve the performance of our API using pure TCP (or WebSockets) and removing the HTTP overhead.

REST verbs are limited

In order to execute an operation using REST it’s necessary to define an HTTP method such as GET (default), PUT, POST, PATH or DELETE [4]. But as the name of this methods suggest, REST is CRUD operations oriented. So what happens if this doesn’t meet our needs? An example could be if we have to validate an entity before saving it. Although there’s always a workaround to solve this kind of issues in REST, the truth is that we don’t want to go down that path if we know there’s a better alternative: JSON-RPC.

With the REST approach we will end up having something like this:

// Request
curl -X POST https://localhost:8080/api/entity/validate —data ‘{…}’

But this looks completely counter-intuitive since we are exposing an action as a false resource. On the other hand if we go with JSON-RPC the result will be much more self-explanatory:

// Request
curl -X POST --data '{
  "jsonrpc": "2.0",
  "method": “validateEntity”,
  "params": [ {…} ],
  "id": 1
}’ https://localhost:8080/api

We have a clear winner.

Passing parameters is complicated

There’re four ways of passing arguments using REST: HTTP Headers, HTTP Body, URL path and URL query.

URL Query:

// Request
curl -X PUT https://localhost:8080/api/users?name=Piers

URL Path:

// Request
curl -X PUT https://localhost:8080/api/users/Stephen

HTTP Body:

// Request
curl -X PUT https://localhost:8080/api/users { “name”: “Josh” }

This can be a bit overwhelming, and sometimes we’re not sure which one to use; but JSON-RPC is here to help us sort this out since it offers a simpler way:

// Request
curl -X POST —data ‘[{
  "jsonrpc": "2.0",
  “method”: “addUser”,
  “params”: { “name”: “Angad” },
  “id”: 1
}]’ https://localhost:8080/api

Batch actions

In REST there’s not a simple and nice way of making batch requests, but with JSON-RPC this is a piece of cake:

// Request
curl -X POST—data ‘[{
  "jsonrpc": "2.0",
  “method”: “addUser”,
  “params”: { “name”: “Zalan” },
  “id”: 1
}, {
  "jsonrpc": "2.0",
  “method”: “addUser”,
  “params”: { “name”: “Dan” },
  “id”: 1
}, {
  "jsonrpc": "2.0",
  “method”: “addUser”,
  “params”: { “name”: “Edgars” }
}]’ https://localhost:8080/api

Other benefits of JSON-RPC

In addition to the above, here are a few other benefits of RPC over REST:

-Only one method to send a request – usually POST for HTTP or send for WebSockets.
-The content of the request is completely separated to the transmission mechanism. All errors, warnings, and data are in the payload of the request.
-Use only one response code to confirm the correct reception of a message – usually 200 OK for HTTP.
-Can be easily ported or shared among different transmission channels such as HTTP/S, WebSockets, XMPP, telnet, SFTP, SCP, or SSH.

The separation of message and transmission channel in a JSON-pure API results in an API that is usually faster, and almost always more reliable, easier to use, easier to port, and easier to debug [7].

Summary

The debate of using JSON-RPC over REST is an interesting one, and the usual response is: “it depends”. Both of them are architectural styles for serving content remotely, using a client-server model. There is also no reason for not using RPC and REST at the same time, but you should have a good argument for doing so.

At Radix we think that if you have to serve web content it may be more convenient to go for a REST API approach, since it has been built to work over HTTP, and there’re many available frameworks and libraries out there that will allow you have a minimum viable API set up in a few hours.

But the truth is that if the API you’re building is more complex to model (HTTP verbs are not enough), it requires to work over other transmission channels and/or maintain a connection open (WebSockets), or the performance is critical, then is better to go with JSON-RPC. In the distributed ledger technologies universe the performance is a fundamental factor, and in Radix much more, since we are already needing to handling thousands of transactions per second on our test nets.

[1] https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming

[2] https://en.wikipedia.org/wiki/Remote_procedure_call

[3] https://searchmicroservices.techtarget.com/definition/Remote-Procedure-Call-RPC

[4] https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods

[5] http://wookieb.pl/why-you-should-consider-rpc-for-internal-api

[6] https://www.smashingmagazine.com/2016/09/understanding-rest-and-rpc-for-http-apis/

[7] https://mmikowski.github.io/the_lie/

Join The Radix Community

Telegram for general chat
​Discord for developers chat
​Reddit for general discussion
Forum for technical discussion
Twitter for announcements
​Email newsletter for weekly updates
Mail to hello@radixdlt.com for general enquiries

Oldest comments (0)