JSON-RPC 2.0: Is null a valid resut in a response?

1,424 views
Skip to first unread message

Jacob

unread,
Apr 14, 2020, 4:34:40 PM4/14/20
to JSON-RPC
I am implementing JSON-RPC in Java. According to JSON-RPC 2.0 regarding response messages:

"Either the result member or error member MUST be included, but both members MUST NOT be included."

I find the term "included" difficult to interpret. Is a value included if it is null?
In particular: can the result of a non-error response be null? , i.e. is this valid:
{
  "jsonrpc": "2.0",
  "result": null,
  "id": 42
}

In our particular workflow we find it useful to return a result like this (in our case it means a reset as opposed to adding data),
but I'm reluctant to allow it since the standard seems vague.

In the 1.0 specification the term included is not used, but instead null (which is confusing in itself, since it is implies
that if the property is absent, the message is invalid). According to the 1.0 spec this doesn't seems to be a valid response:

{
  "result": "something",
  "id": 42 
}

You are forced to send the following:
{
  "result": "something",
  "error": null,
  "id": 42   
}
Confusing indeed.

Thanks!

Nathan Fischer

unread,
Apr 14, 2020, 7:26:20 PM4/14/20
to JSON-RPC
I would interpret it as "included" meaning that the field is present with any value.
This will prevent you from encountering any bugs with software that has some logic like
responseObject.keys.contains("error")
Even if you send null, that code is going to assume you've sent an error response.

Jacob

unread,
Apr 15, 2020, 8:15:40 AM4/15/20
to JSON-RPC
Thanks Nathan,

This is how I interpret it as well, but I would very much like to get it confirmed,
preferably in the 2.0 specification itself.

Alexandre Morgaut

unread,
Apr 19, 2020, 1:51:24 PM4/19/20
to JSON-RPC
The spec says:

"5.1 Error Object"
"When a rpc call encounters an error, the Response Object MUST contain the error member with a value that is a Object with the following members:"

the mentioned members being "code", "message", and "data" (optional)

So when the error member contains null, and not such Object, the response should not be considered as an error

Note:
- if there is no valid "error" object and there no "result" member in the response, the response is then invalid... This is a wrong implementation, a server error, or potentially caused by a bad proxy/middleware modification, 

Martin Barker

unread,
Apr 20, 2020, 6:13:16 AM4/20/20
to json...@googlegroups.com
So my understanding of this is,

When a response should be given so the call was successful, "response" can be given as null or any other supported JSON Value type, (Array, Object, String, Number, NULL), "error" should be omitted.
When an error should be given so the call was unsuccessful, "response" should be omitted, and "error" should be an object that contains "code", "message" and optionally include "data" (E.G a stack trace if in debug mode)

From the spec "
result
This member is REQUIRED on success.
This member MUST NOT exist if there was an error invoking the method.
The value of this member is determined by the method invoked on the Server.
error
This member is REQUIRED on error.
This member MUST NOT exist if there was no error triggered during invocation.
The value for this member MUST be an Object as defined in section 5.1.
"

So it is one or the other, never both.


--
You received this message because you are subscribed to the Google Groups "JSON-RPC" group.
To unsubscribe from this group and stop receiving emails from it, send an email to json-rpc+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/json-rpc/ab622da8-2e79-4953-981e-3abbf4e8ae30%40googlegroups.com.

Alexandre Morgaut

unread,
Apr 21, 2020, 3:40:48 AM4/21/20
to JSON-RPC

When a response should be given so the call was successful, "response" can be given as null or any other supported JSON Value type, (Array, Object, String, Number, NULL), "error" should be omitted.
When an error should be given so the call was unsuccessful, "response" should be omitted, and "error" should be an object that contains "code", "message" and optionally include "data" (E.G a stack trace if in debug mode)

I think you meant "result" and not "response" ;-)
Otherwise with a null response you would have no result, no version, nothing..., and with an omitted response you would have no error neither...


Notes:


1 - As the spec says that the "error" menber "MUST NOT exist if there was no error triggered during invocation", adding a null "error"  member in a valid response makes it a malformed JSON-RPC server response

The service is "buggy" and you should report an issue as you can be sure that some JSON-RPC client correctly support such response


2- But, as a JSON-RPC client author,  because on the Web you often have no choice and can hardly fix how the server behaves, it is generally wize to follow the "robustness principle" aka the "Postel's law" who applied it to TCP 

"be conservative in what you do, be liberal in what you accept from others."


Especially if you write a client with a specific server in mind

In that case, the response:
- contains a "response" member
- doesn't contain a VALID error member

So there is no much ambiguity on the expected behavior

The real problem would be if you had a "response" member and a valid "error" member
Here a again you could support a "config" that allow the code using the client implementation would choose to interpret it:
- as an error by default
- as a valid response by default
- as an error if the result is null (even if it is a valid result value)

Following such concept you can see how complex the client implementation can become (imagine how the web browser code looks like)
This is why it is interesting for coders to have multiple client implementations available:
- some very strict ones failing on such malformed response but with a light and fast code
- some more permissive, with more complex and heavy code, for when you have no much choice regarding the services you need to connect to

Anyway "ALWAYS START BY REPORTING AN ISSUE TO FIX THE SERVER"

:-)



To unsubscribe from this group and stop receiving emails from it, send an email to json...@googlegroups.com.

Martin Barker

unread,
Apr 21, 2020, 6:02:01 AM4/21/20
to json...@googlegroups.com
I would agree, however, there is also something to say about the architecture of the client, it should never be expecting both, 

In PHP, C# and Javascript that I have used it's entirely possible to parse to a generic object and if exists/defined response.error then create an object of a type JSONRPC.Error or JS and configure it to have the values all inside the API Wrapper.

E.G C# pseudocode 
namespace JSONRPC;
class JSONRPC.response { int id; string jsonrpc; }
class JSONRPC.result extends JSONRPC.response { string result; }
class JSONRPC.error extends JSONRPC.response { JSONRPC.errorObj error; }
class JSONRPC.errorObj { int code; string message; string data = ""; }

That why your actually client software not the API client can just do 
JSONRPC.response response = API.fetch(...);
try{
  string resultFromServer = ((JSONRPC.response)response).result;
  // use result
}catch(exception){
  // handle error or throw it up to be caught by main client
}

To unsubscribe from this group and stop receiving emails from it, send an email to json-rpc+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/json-rpc/6100715e-c466-40cf-93c4-353428607985%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages