JSON-RPCUser Guide
Overview
An implementation of the JSON-RPC v2.0 specification.
JSON-RPC is used by the Language Server Protocol (LSP) to serialise messages.
Use JSON-RPC to invoke methods on a class instance.
Quick Start
using afJsonRpc class Example { Void main() { sink := ExampleSink()// this will receive the method callsjsonRpc := JsonRpc(sink)// rpc call with positional parametersres1 := jsonRpc.call( """{ "jsonrpc": "2.0", "id" : 1, "method" : "subtract", "params" : [42, 23] }""".in ) echo(res1)// <-- {"jsonrpc": "2.0", "result": 19, "id": 1}// rpc call with named parametersres2 := jsonRpc.call( """{ "jsonrpc": "2.0", "id" : 3, "method" : "subtract", "params" : {"subtrahend": 23, "minuend": 42} }""".in ) echo(res2)// <-- {"jsonrpc": "2.0", "result": 19, "id": 3}} } class ExampleSink { Float subtract(Float minuend, Float subtrahend) { return minuend - subtrahend } }
Multiple Sinks
For larger RPC implementations you will want multiple sinks for your methods. For this, pass a Str:Obj
map to JsonRpc
where the Objs are the sinks, and the Strs are a matching prefix.
jsonRpc := JsonRpc([ "text/" : TextSink() "image/" : ImageSink() ])
Then the RPC call {"jsonrpc": "2.0", "method": "text/update"}
would be forwarded to the method TextSink.update()
.
And the RPC call {"jsonrpc": "2.0", "method": "image/update"}
would be forwarded to the method ImageSink.update()
.
For optimised calls, use a custom dispatchFn
:
JsonRpc(..., [ "dispatchFn" : JsonRpc.multiSinkDispatchFn('/') ])
Transport over HTTP
Use afBedSheet to create a HTTP server for receive your RPC calls.
JSON to Fantom object mapping
Use afJson to map JSON to Fantom objects.
json := afJson::JsonConverters() jsonRpc := JsonRpc(..., [ "invokeFn" : JsonRpc.convertingInvokeFn |type, val| { type != null ? json.fromJsonVal(val, type) : json.toJsonVal(val) } ])