68
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!
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;
}
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"
}
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.
68