Remote Procedural Call Style APIs in 2020

RPC doesn't get as much airtime as GraphQL and even REST these days. However, if you are building a purely internal tool, wont most of the endpoints skew towards RPC over anything else? Even if a team picks GraphQL as a means to communicate internally, many of your queries and mutations are going to have a distinct RPC feel to them.

Coming to this conclusion, after writing what feels like hundreds of REST APIs, and a few GraphQL ones, has been a bit of a surprise. Especially with my strong emotions (positive) around REST and HATEOS.

Due to all this API soul searching, I decided to explore the current crop of RPC like libraries in Node. The most promising one turned out to be one titled: Wildcard.js. Wildcard acts like most Express middleware. It creates a catch all namespace that then calls function names depending on the route called in the namespace.

Most RPC like APIs, much like GraphQL adopt a POST only approach to HTTP Methods (more info on JSON RPC). Wildcard goes one step further here; providing developers with a GET route for each of its generated POST routes. This allows developers a way to view and explore the API much like GraphiQL.

Polka, is a splendid and now my favorite HTTP library for Node. It's small, simple, and has a lightweight dependency footprint. However, its' middleware signature differs significantly from that of Express. This means that most middleware that functions with Express, won't with Polka. Due to this, the example below and repo showcases a manual way of setting up Wildcard with any Node http library or framework.

Here's to more Functions over HTTP powered by JavaScript's new love of type systems (Flow, Typescript or Hegel).

Example server config:

const polka = require("polka");
const { getApiHttpResponse } = require("@wildcard-api/server");
polka()
  .all("/_wildcard_api/*", async (req, res) => {
    const { url, method, body: originalBody } = req;
    const rpcResponse = await getApiHttpResponse(
      { url, method, originalBody },
      {}
    );
    const { body, statusCode, contentType, etag } = rpcResponse;

    res.writeHead(statusCode, { "Content-Type": contentType, ETag: etag });
    res.end(JSON.stringify({ body }));
  })
  .listen(3000, (err) => {
    if (err) {
      throw err;
    }

    console.log(`running... in ${process.env.NODE_ENV} mode`);
  });

Link to repository

What's your opinion on RPC style APIs for internal use? Reach out to me on Twitter and let's chat