DEV Community

Viacheslav Poturaev
Viacheslav Poturaev

Posted on

JSON-RPC 2.0 with Swagger UI

JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. Primarily this specification defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over http, or in many various message passing environments. It uses JSON (RFC 4627) as data format.

It is designed to be simple!

https://www.jsonrpc.org/specification

There are cases when JSON-RPC might be a better fit than other technologies. Especially when API is consumed by legacy systems with high cost of change.

  • Built-in semantics for batch requests offloads parallel processing to back end to optimize performance of slow synchronous clients.
  • Uniform request/response structure makes it easy implement a generalized transport-level client that does not need to be updated on API extension.

Unfortunately, documenting JSON-RPC in machine-readable way lacks an established and popular standard (like OpenAPI for REST).

There is OpenRPC, which hopefully will grow its ecosystem and users base.

Another great tool to serve documentation and web client for REST APIs is Swagger UI. With a bit of tweaking/hacking we can reuse it for JSON-RPC 2.0.

SwaggerUIBundle constructor accepts requestInterceptor in configuration. Provided that JSON-RPC method is available as OpenAPI path item, this interceptor can reroute request and envelope it as JSON-RPC.

Mind /rpc in the following code, it is the path to JSON-RPC endpoint, and it may vary from one API to another.

requestInterceptor: function(request) {
    if (request.loadSpec) {
        return request;
    }
    var url = window.location.protocol + '//'+ window.location.host;
    var method = request.url.substring(url.length);
    request.url = url + '/rpc';
    request.body = '{"jsonrpc": "2.0", "method": "' + method + '", "id": 1, "params": ' + request.body + '}';
    return request;
}
Enter fullscreen mode Exit fullscreen mode

Now, if you want to integrate Swagger UI with your JSON-RPC API you need to create a fake OpenAPI schema with structures of your methods.

{
  "openapi":"3.0.3",
  "info":{
    "title":"JSON-RPC Example",
    "description":"This app showcases a trivial JSON-RPC API.",
    "version":"v1.2.3"
  },
  "paths":{
    "nameLength":{
      "post":{
        "summary":"Test","description":"Test Description",
        "operationId":"nameLength",
        "requestBody":{
          "content":{
            "application/json":{"schema":{"$ref":"#/components/schemas/JsonrpcTestInp"}}
          }
        },
        "responses":{
          "200":{
            "description":"OK",
            "content":{
              "application/json":{"schema":{"$ref":"#/components/schemas/JsonrpcTestOut"}}
            }
          }
        }
      }
    }
  },
  "components":{
    "schemas":{
      "JsonrpcTestInp":{"type":"object","properties":{"name":{"type":"string"}}},
      "JsonrpcTestOut":{"type":"object","properties":{"len":{"type":"integer"}}}
    }
  },
  "x-envelope":"jsonrpc-2.0"
}
Enter fullscreen mode Exit fullscreen mode

Screenshot

This approach has been automated with a github.com/swaggest/jsonrpc Go library that serves self-documented JSON-RPC from use case interactors. Support for OpenRPC might be implemented too.

Oldest comments (0)