Wandering about for the first time in the Json classed of Berlin, I have a few questions from a noob perspective, which I hope someone with experience can enlighten me on.
I am implementing the JsonRPC protocol, where a request basically looks like this:
{
“jsonrpc”:”2.0″,
“method”:”JSon.MethodName”,
“params”: {
“aIntParam”: 100,
“aStrParam”:”A string”
},
“Id”: “UniqueIdValue”
}
I.e. The method name may vary, and with it the “params” – or implicitly, the type of the JSon object that recides in “params”. The challenge here is that I don’t know the type, until I have identified the content of “method”.
Using TJSon, it is trivial to get the value – but relatively costly, since it will also parse “params” – which can be large and complex.
// property fields omitted for brevity
class TJSonRPC = class
public
property jsonrpc: String;
property method: String;
property params: String;
property id: String;
end;
And if I parse
var
rpc: TJsonRPC;
begin
rpc := TJSon.JsonToObject(ReceivedJsonString);
“rpc” will contain the correct string values in the “jsonrpc”, “method” and “id” fields – while “params” will be an empty string, since it was an unknown object type.
I use “method” to look up the associated “params” type, as well as the handler methods. Now I have to reparse the whole thing again – instead of avoiding the first parsing of params, and then only parsing params with the right type later.
So, after this long intro – my question is: Can I persuade TJSon to treat “params” as it was a string and not an object for the TJsonRPC class?
You should Register a Converter for the params property so you can parse everything at once in a case record structure for instance.
docwiki.embarcadero.com – Serializing User Objects – RAD Studio
JSON is not very good at polymorphism in strongly typed languages (no surprise given it originated in java script).
I would put a wrapper around the json object to get the fixed fields and return the params as json value to be able to deal with it.
Edit:Paul TOTHSince I don’t know the class at receiving the JsonRPC message, that’s not possible.Wait a sec – I think I misread you. I’ll have a look at the custom Converter.
Stefan Glienke Currently I use a class without params to parse the package, before parsing again with params when I know the object type, but the TJson class will always parse the entire structure.
I could make a pseudo wrapper that just do a Pos(‘”method”:’, aJSonString) to find the method fast, but it is a bit dirty, and potentially easy to break with spacing or case.
If you use the mORMot serializer, you can just define the “Params” property as RawJSON type, and it will do what you expect. Or define it as a variant, and it will be filled with a TDocVariant custom type, which you may resolve easily with late-binding, typing directly Params.aIntParam or Params.aStrParam in your code – so Stefan Glienke you can have a weakly typed fields in Delphi. But not with the RTL JSON library, for sure.
Lars Fosdal did the converter get you any further?
Jeroen Wiert Pluimers I have yet to try it out, as other matters took the time.
Lars Fosdal you might want to check out plus.google.com – How does one convert a Delphi enum to a JSON value, with different specific v…