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:JsonRpc
class Example {
    Void main() {
        sink    := ExampleSink()  // this will receive the method calls
        jsonRpc := JsonRpc(sink)
        // rpc call with positional parameters
        res1 := 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 parameters
        res2 := 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().
JSON to Fantom object mapping
Use afJson to map JSON to Fantom objects.
conv := afJson::JsonConverters()
opts := Str:Obj[
    "fromJsonFn" : |Obj? jsonVal, Type argType ->Obj?| { conv.fromJsonVal(jsonVal, argType) },
    "toJsonFn"   : |Obj? returnVal             ->Obj?| { conv.toJsonVal(returnVal) },
])
jsonRpc := JsonRpc(sink, opts)