-2

I have to integrate with another company's API, which they unfortunately decided to write in JSON RPC 2.0.

If you're not familiar with JSON RPC, it's a lightweight RPC protocol that defines a request that must always have the structure: jsonrpc, method, params, id.

Here is an example request I might make:

{
    "jsonrpc": "2.0",
    "method": "100",
    "params": ["en", 123455678, "5.00", [["3", "1.00", "1"], ["4", "4.00", "1"]]],
    "id": 100
}

Here is an example response that I might get back:

{
    "jsonrpc": "2.0",
    "id": 100,
    "result": [
        "0",
        "0",
        "0",
        "20180723-0",
        []
    ]
}

I already develop my app APIs in C# and host them on Azure, so I was thinking it might be easiest to create a class library in C# and reference the library in my API (where I would need to use it).

But as I started to develop the API in C# I started to realize just how difficult it would be since C# is so strongly typed. I think it would still be possible in C# thanks to dynamic typing, but it seems somewhat overkill to use C#.

The other option I was thinking of would be to use NodeJS, or even Python. I've created some small NodeJS scripts before and hosted them in AWS Lambda, but I wasn't happy with the AWS Lambda startup delays. This application deals with gift cards, so I want the integration to be as fast as possible.

At least with NodeJS and Python they're not as strongly typed, and therefore accessing the specific values of the requests I get back would be fairly easy compared with what I think I would have to do with C#. Also, I'm the sole developer at my company, so I'm willing to sacrifice a little maintainability for time.

  • 1
    C# has the dynamic keyword. There's no reason at all you couldn't do what you want in C#. It's unclear to me why strong typing is a difficulty in your scenario. – Robert Harvey Jul 23 '18 at 15:47
  • So I can create an array in C# that has some members that are strings and others that are arrays/numbers? – Joshua Kemmerer Jul 23 '18 at 15:51
  • @JoshuaKemmerer that would be object[] – Ewan Jul 23 '18 at 15:54
  • @Ewan: Which just begs the question again. – Robert Harvey Jul 23 '18 at 15:54
  • @JoshuaKemmerer: If you need that kind of flexibility in your params, it seems like some routine string jiggerypokery would take care of that. – Robert Harvey Jul 23 '18 at 15:55
1

It seems like you can implement the pattern with generics

public class JsonRpcRequest<T>
{
    public string jsonrpc {get;set;} = "2.0";
    public int id {get;set;}
    public T params {get;set;} //serialise as object or array
    public string method {get;set;}
}

public class JsonRpcResponse<T>
{
    public string jsonrpc {get;set;}
    public int id {get;set;}
    public T result {get;set;}
    public Error error {get;set;}
}

Or simply deal have custom serialisation in your client class.

Note: sending parameters

the spec allows for two ways of sending parameters:

Parameters for a procedure call can be specified by-position, or by-name.

by-position: params MUST be an Array, containing the parameters in the right order (like in JSON-RPC 1.0).

by-name: params MUST be an Object, containing the parameter-names and its values. The names MUST match exactly (including case) the names defined by the formal arguments. The order of the name/value-pairs is insignificant.

The standard Json.Net serialiser will serialise your params object as a json object, which will meet the second way of sending them.

If you need to send as an array then you can either use a custom serializer for the type, OR manually convert to an object array in the Client Method ie

public void GetData(int p1, string p2)
{
    JsonRpcRequest.params = new object[] {p1,p2};
    send(JsonRpcRequest);
}
  • This kinda just begs the question: what do you use for T? – Robert Harvey Jul 23 '18 at 15:51
  • to quote the spec "The Value that was returned by the procedure. Its contents is entirely defined by the procedure" so presumably whatever class you would deserialise to if you weren't using JsonRpc to wrap the call. As you point out in your comment, its unclear what the problem is with the strong typing – Ewan Jul 23 '18 at 15:53
  • Maybe I'm just overthinking it, but the problem I thought I might have with strong typing is that I would have to create types for every single response and request I create. There are nine different requests types I have to create, and another nine for the responses, so I thought I might have to create classes for 18 different objects. And maybe that is the "right" way to do it, but I think I'll just do it the hacky way and that should work just fine. – Joshua Kemmerer Jul 23 '18 at 15:59
  • You can probably avoid creating object for the requests, if the reponses are single built in types like int, string or arrays of them, then you are good there too. Only create objects when you have objects being returned to you. – Ewan Jul 23 '18 at 16:02
  • but yeah, creating objects that match the response is pretty standard, its not clear how JsonRpc makes it any different? – Ewan Jul 23 '18 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.