Monday, 29 January, 2018 UTC


Summary

Introduction
Services over an HTTP endpoint come in many shapes and sizes. The style you adopt may flow out the problem you are trying to solve. In programming, there is usually more than one valid approach and this is also true for web services.
When it comes to services over the web there is a lot of confusion. Remote-Procedure-Call (RPC), for example, is one style of creating web APIs. Representational State Transfer (REST), on the other hand, is another approach. Each style has a different implementation. The confusion stems from the fact both styles communicate over HTTP. The similarities at the HTTP protocol level can trick you into thinking everything is REST.
In this take, we’d like to delve into the RPC versus REST style for web APIs. There are key differences that might be useful the next time you need to implement a web service.
Please note there is no right or wrong here. Each separate style serves a different purpose. Both styles have pros and cons.
But, Why Should You Care?
Like with any programming problem, picking the best implementation depends on the job at hand. Knowing where the advantages are for each approach will help you pick the best solution.
An RPC endpoint is useful for working with a narrow view of the data. This reduces the bandwidth you use on the network and simplifies the service. You can be as specific or as narrow as you want as long as it does what you need. What is nice about RPC is that you have a way of creating services that do one job well.
A REST endpoint treats the request like making a call to a resource. The resource becomes the domain that has the data. The resource does not concern itself with functionality at all. It is only a place where you contain data and do with it as you see fit. What is nice about REST is that you have a resource API you can then call from many clients. REST API’s only concern is all the data that belongs to that specific domain.
With the theory in place, what does an RPC endpoint look like? What about a REST endpoint?
We’ll use Node for all endpoints, so let’s use the http module:
var http = require('http');  
For the demo, assume you have a list of elusive cats. To keep it simple we will only be populating it with a snow leopard. For this example, we want you to focus on only key differences between each implementation.
Below is the list of elusive cats:
var CAT_ID = 1;

var ELUSIVE_CATS = [  
  { id: CAT_ID, name: 'Snow Leopard', conservationStatus: 'Vulnerable' }
];
What is RPC?
For the RPC endpoint assume the client only cares about the name of the cat based on id. We expect a JSON from the service call that has a name property.
For example:
var app = http.createServer(function onRequest(req, res) {  
  if (req.url === '/getElusiveCatNameById?id=' + CAT_ID) {

    var cat = ELUSIVE_CATS.find(function onElusiveCat(c) {
      return c.id === CAT_ID;
    });

    res.setHeader('Content-Type', 'application/json; charset=utf-8');

    res.end('{' + '"name":"' + cat.name + '"}');
  }
});
Note the URL matches an endpoint /getElusiveCatNameById with a query string id parameter. RPC style endpoints are notorious for specifying the function in the URL. This is convenient because by looking up the URL you can decipher what it does and what you get in return. The service does not concern itself with all the properties available so it is simple.
To fire up this Node endpoint make sure you are listening on a port:
app.listen(1337);  
Testing the RPC style endpoint yields these results:
>curl http://localhost:1337/getElusiveCatNameById?id=1
{"name":"Snow Leopard"}
What is REST?
For the REST endpoint, we must treat it as a resource. Imagine we have a domain of elusive animals found in the wild. Within this elusive domain of creatures, you will find elusive cats.
For example:
var app = http.createServer(function onRequest(req, res) {  
  if (req.method === 'GET' &&
    req.url === '/elusive/cat/' + CAT_ID) {

    var cat = ELUSIVE_CATS.find(function onElusiveCat(c) {
      return c.id === CAT_ID;
    });

    res.setHeader('Content-Type', 'application/json; charset=utf-8');

    res.end('{"id":' + cat.id + ',"name":"' + cat.name +
      '","conservationStatus":"' + cat.conservationStatus + '"}');
  }
});
Note the URL matches an endpoint /elusive/cat with an id of 1 appended at the end. For this REST endpoint, the HTTP verb or method matters. A GET request tells the service we want everything under the cat domain with all property fields. If you inspect the JSON returned this is why you get back the entire domain. This is nice because you are building a domain boundary that defines all the data it has. With this, any client that wants cat data can use it because the service allows many ways of using the data.
Testing the REST style endpoint yields these results:
>curl http://localhost:1337/elusive/cat/1
{"id":1,"name":"Snow Leopard","conservationStatus":"Vulnerable"}
Conclusion
RPC style endpoints are great when you want only one job done well. This makes it useful to one or two app clients because it is niche a service. RPC endpoints can implement business logic inside the service given that it only does one thing. This adds simplicity and clarity to the service.
For a REST endpoint, you must treat it like a resource that provides domain data. The reward is you are now segregating data into separate domains. This makes it useful for when you have any number of apps requesting data. This approach attempts to decouple data from application or business logic.
The answer to which style to implement is the usual “it depends.” A distributed large scale system may benefit from REST while a smaller monolithic one does not. MVC systems with a basic CRUD can benefit from RPC as long as there is little need to scale.
When choosing either approach or style it is key to know the differences. There is no right or wrong here. What is more important, is to know which approach solves for the job at hand.