I agree that this is wasteful and probably unnecessary in the response.
I have a server system that supports 1.0, 1.1, and 2.0, so if this
field is in requests, it's the simplest way for my system to understand
what sort of response the client wants.
If a client supports multiple versions, having it in the response helps
the client understand how it should parse the response (particularly for
errors, although the JSON-RPC specs *can* all be compatible with each
other in error formats, theoretically).
> In our case
> all our APIs are JSON-RPC 2.0 or above so filling this in is wasteful so
> while we’re happy to accept it on input, and even reject requests that
> specify a value other than “2.0” we don't reject requests that omit this
> value and we do not populate it in the output.
I think that more or less, it's safe to ignore it. In my current server
implementation, I just assume that a request is 2.0 if it doesn't
specify otherwise, as well.
> The specification section 4 defines any request that does not contain an
> ‘id’ to be a ‘notification’.
I agree that this is useless and unfortunate--I wrote to the list about
it a few months back, also.
> however we vary from the spec by default for the following codes:
> -32601 - Method not found. Instead we use the HTTP code 404 NOT FOUND
> -32602 - Invalid parameters. Instead we use the HTTP code 400 BAD REQUEST
> -32603 - Internal error. Instead we use the HTTP code 500 INTERNAL
> SERVER ERROR for failures in the Apiary stack and the spec code for
> failures caused by backend errors.
I think that's pretty much in line with the JSON-RPC Over HTTP spec, no?
> We do not currently echo back the apiVersion in the response and it’s
> worth discussing whether we should do so particularly when no apiVersion
> is specified in the request and the server chooses one by default.
Mmm, since your APIs are centralized, I don't think anybody's going to
be implementing a client that attempts to support more than one API
version at once, right? If there are identical methods across different
APIs that would possibly get updated separately, though, there might be
a value in specifying the apiVersion in the response.
-Max
--
http://www.everythingsolved.com/
Competent, Friendly Bugzilla and Perl Services. Everything Else, too.
Folks,
As announced at Google I/O were working on launching JSON-RPC support for most of our newer APIs. We've had success with using JSON-RPC for the client with OpenSocial so we are broadening our support for it. In particular JSON-RPC has proven useful as a dispatch mechanism for it's very obvious batch support and naming and parsing conventions that work well in Javascript clients. This by no means indicates that we are abandoning RESTful APIs or that we design first as RPC, quite the opposite in fact. It's simply that for newer APIs we support there is no reason to limit ourselves and our clients to a single transport mechanism for all use cases.�
There are a few areas where we are just non-compliant and have some questions about the value of what the spec is requiring. Let me know what you think as we'd like to launch fairly soon and we're very interested in the communities feedback.
CheersLouis
JSON-RPC version
The specification sections 4 & 5 mandates that the value
�jsonrpc� : �2.0�
be provided at the top-level of every request and response. In our case all our APIs are JSON-RPC 2.0 or above so filling this in is wasteful so while we�re happy to accept it on input, and even reject requests that specify a value other than �2.0� we don't reject requests that omit this value and we do not populate it in the output.
Absence of �id� to indicate that no response should be produced
The specification section 4 defines any request that does not contain an �id� to be a �notification�. A notification is a request the response to which the caller does not care about and so the system should not produce a response object. In the case of a batch of requests this would mean that the cardinality of the batch response may not necessarily match that of the request. Our current behavior is to always produce a response even if an id is omitted primarily because even if something is dispatching an asynchronous job there is still the need for parameter validation which should be confirmed to the caller. Does anyone make significant use of the behavior described in the spec of perceive any performance advantage from it?
Error code alignment
We produce codes per the specification for:
-32700 - Invalid JSON
-32600 - Invalid request object
however we vary from the spec by default for the following codes:
-32601 - Method not found. Instead we use the HTTP code 404 NOT FOUND
-32602 - Invalid parameters. Instead we use the HTTP code 400 BAD REQUEST
-32603 - Internal error. Instead we use the HTTP code 500 INTERNAL SERVER ERROR for failures in the Apiary stack and the spec code for failures caused by backend errors.
This variance is maintained primarily for compatibility with the OpenSocial JSON-RPC implementation in Apache Shindig which followed the same pattern. I think the error codification in the spec is one of its weaker areas about which there is good discussion on one of the other threads here. We use the 'data' field inside an error response to carry an array of more detailed error objects as our system allows for APIs to report secondary errors.
- location and name of invalid parameters- textual namespaced error codes (see the other thread for discussion)- debug information and identifiers for request tracing- help links to reference documentation if requested
apiVersion:
The specification doesn�t provide a mechanism for describing different versions on the same API. We added support for this by defining an �apiVersion� field at the top level of the request which contains a string literal of the version name. E.g
{
�id : �12345�,
�method : �language.diacritize.get�,
�apiVersion : �v2�
...
}
We do not currently echo back the apiVersion in the response and it�s worth discussing whether we should do so particularly when no apiVersion is specified in the request and the server chooses one by default.
--
You received this message because you are subscribed to the Google Groups "JSON-RPC" group.
To post to this group, send email to json...@googlegroups.com.
To unsubscribe from this group, send email to json-rpc+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/json-rpc?hl=en.
With respect to Louis Ryan’s comments:
Absence of ‘id’ to indicate that no response should be produced
The specification section 4 defines any request that does not contain an ‘id’ to be a ‘notification’. A notification is a request the response to which the caller does not care about and so the system should not produce a response object. In the case of a batch of requests this would mean that the cardinality of the batch response may not necessarily match that of the request. Our current behavior is to always produce a response even if an id is omitted primarily because even if something is dispatching an asynchronous job there is still the need for parameter validation which should be confirmed to the caller. Does anyone make significant use of the behavior described in the spec of perceive any performance advantage from it?
We use such notifications extensively for client/server applications where the server asynchronously notifies the client of state changes of other clients of the server. These state changes are published to all clients. There is no benefit in having the clients respond to the server notifications, and performance would suffer if the server had to field responses from each of the clients, especially when the the server is pushing notifications every second or two to each of a thousand clients. In addition, in a common carrier mobile environment where the carrier charges for traffic, or traffic in excess of a monthly limit, producing a response to the notification may double the cost or possibly worse.
Best regards,
Henry Unger
Hitech Systems, Inc.
Folks,
As announced at Google I/O were working on launching JSON-RPC support for most of our newer APIs.
There are a few areas where we are just non-compliant and have some questions about the value of what the spec is requiring. Let me know what you think as we'd like to launch fairly soon and we're very interested in the communities feedback.
JSON-RPC version
The specification sections 4 & 5 mandates that the value
“jsonrpc” : “2.0”
be provided at the top-level of every request and response. In our case all our APIs are JSON-RPC 2.0 or above so filling this in is wasteful so while we’re happy to accept it on input, and even reject requests that specify a value other than “2.0” we don't reject requests that omit this value and we do not populate it in the output.
Absence of ‘id’ to indicate that no response should be produced
In the case of a batch of requests this would mean that the cardinality of the batch response may not necessarily match that of the request.
Our current behavior is to always produce a response even if an id is omitted primarily because even if something is dispatching an asynchronous job there is still the need for parameter validation which should be confirmed to the caller.
Does anyone make significant use of the behavior described in the spec of perceive any performance advantage from it?
Error code alignment
apiVersion:
The specification doesn’t provide a mechanism for describing different versions on the same API.
We added support for this by defining an ‘apiVersion’ field at the top level of the request which contains a string literal of the version name. E.g
{
id : ‘12345’,
method : “language.diacritize.get”,
apiVersion : ‘v2’
...
}
So, I've been thinking about this, because I'm not opposed to
notifications--I'm simply opposed to the semantics of "no id means this
is a notification".
Instead of this, why don't we include a field "notification: true" that
means "this SHOULD NOT get a response"?
That would preserve notification functionality while allowing the
majority of requests to be simpler by not containing an id.
Instead of this, why don't we include a field "notification: true" thatmeans "this SHOULD NOT get a response"?
That would preserve notification functionality while allowing the
majority of requests to be simpler by not containing an id.
Given that responses may be asynchronous and unordered, I agree that having the id field should be mandatory when a response is expected, otherwise it would be impossible for a client to correlate a response with its request at the protocol level. From a conceptual basis, I have been taking advantage of this type of behavior (presence of id means response, absence means notification) for almost 25 years in public safety applications.
Henry Unger
That's true, but:
(a) I've never needed the id. For example, I'm often using the YUI
DataSource module, which keeps track of requests separately. In fact,
any good async framework keeps track of requests and responses in some
way of its own.
and
(b) It's essentially putting an implementation detail into a protocol spec.
So what I'm saying is that I'd like it to simply be optional.
On 09/04/2010 07:52 AM, Derrell Lipman wrote:That's true, but:
> An id allows the responses to multiple async requests to be
> associated with their request when the response is received. If no id is
> sent with a request that requires a response, only one could be sent at
> a time or there would be no way to correlate the responses to their
> requests.
(a) I've never needed the id. For example, I'm often using the YUI
DataSource module, which keeps track of requests separately. In fact,
any good async framework keeps track of requests and responses in some
way of its own.
and
(b) It's essentially putting an implementation detail into a protocol spec.
Yeah, I agree, and it should be optional. If I personally don't need a
way to associate requests with responses, then why force me to include
the id?
> The client side (or whomever is
> the issuer of the request) would need to be customized for each server
> it wants to make requests of.
Yes, if there wasn't an id field at all in the spec, that would be
true. But there is an id field, I just want it to be optional.
> I believe that having the id field as part of every request and response
> (with the possible exception of the special type of request called a
> notification) adds to the standardization that allows clients to be
> used with multiple servers.
Notifications would also work with a "notification: true" field.
That sounds good.
> The point here is, if you are making an XHR then both server and client
> already know that your request's answer should in that very same session
> and unless you are making a batch request, using an id here is
> meaningless. Though if you are using or will use the new "WebSockets"
> API you still should provide an id which makes me think that the only
> use case of omitting the id seems this XHR thing and adding a relatively
> long name like "notification" just for this case not sounds plausible to me.
There could be lots of scenarios, though. I think that when designing a
protocol like this, it's definitely important to have reference
implementations and an idea of what the real-world applications would
be, but it's also important not to design it explicitly for a list of
valid situations, because there's always going to be situations you
can't predict. (See also:
http://www.codesimplicity.com/post/designing-too-far-into-the-future/ )
So, instead, it's best to design it to be as flexible as reasonably
possible. Making "notification" an explicit element leaves much more
flexibility in the protocol than re-using the "id" field for that purpose.
I think that a shorter name than "notification" would be good, though,
if anybody has some ideas.
I thought about that, too, but that effectively makes the "notify"
field mandatory if you want a reply, which adds an extra unnecessary
item in every call and also would break backwards-compatibility with 2.0.
Ahhh, okay. Yeah, I misunderstood and thought that "notify: true" meant
"send me a response". :-)
> but maybe that's unintuitive because it is a verb.
Yeah, there might be some better term to use....
Ajax-
type one-off requests make this hard to see, but the id is vital to
the client sorting out its many messages.
True in some situations, but not in all situations.
> It has little to do with the server, and probably never should.
Okay. In that case, the protocol should also account for servers that
don't need it. I can tell you that thus far in all of the situations in
which I have used JSON-RPC, I have never needed the "id" field in a
conceptual or factual way.
id's are required to signify the need for a response object being sent back. The lack there of signifies the client not needing a response object. Changing this should not be done lightly and without really good reason. This is about the client stating its intentions.
It's a very significant and unnecessary complexity in an HTTP GET
situation. Generally, imagine telling people that your API looks like this:
rpc?method=Hello.world&jsonrpc=2.0&id=1
versus telling people that your API looks like this:
rpc?method=Hello.world
In fact, #2 can be implemented as a simple REST call, like:
rpc/Hello/world
Whereas #1 cannot be (without significant additional and unnecessary
complexity).
This is just one example.
> providing an ID is not a big deal as everybody seems to agree, so just > do it if you do need feedback. It's a very significant and unnecessary complexity in an HTTP GET situation.
Feed it to any endpoint : Content-Type: application/json-rpc Content-Length: ... paste the json blob and ... VOILA !Try doing the same by GET :
The fundamental "code smell" here is that id has two distinct purposes:
1) the id to pass back in the response, to be available to the client
to associate responses with requests.
2) indicates a non-notification by being present
Any time you dual-purpose a field this way, you are likely to end up
with boundary conditions where the dual-purposing doesn't make sense.
I believe this is the underlying reason people are getting so het up
over this seemingly trivial detail.
A far more sensible arrangement would be a separate "notification"
parameter (defaulting to false if not present).
This would then allow "id" to be optional, and to be omitted when the
client doesn't need it.
I'd be happy to write this up as an extension to the spec, but I'm
not really sure whether such a rule change would actually be welcome
to those writing json-rpc libraries without an actual version bump
to json-rpc itself.
Yeah. Did you read the part at the bottom where I said that it was only
one example?
> 1. Base 64 param value
That's unnecessary and I've discussed how unnecessary it is in another
thread, and we all seemed to agree.
In response to the rest of your post, and as a completely unrelated
side note to this thread, HTTP GET support is very useful and
considerably simplifies things for many consumers. It's also an
excellent foundation to build a REST-based JSON-RPC service on.
Can you clarify this? It doesn't agree with my understanding. My
understanding is that JSON-RPC /is/ the async framework, and the id /is/
the way it keeps track of requests and responses.
I have worked on both a Common Lisp JSON-RPC library and a
Firefox-specific one, run over sockets. Both use the id field to manage
the response and request tracking, and neither has any alternative means
of tracking them.
The whole beauty of JSON-RPC, from my POV, is that it provides a dead
simple asynchrony framework, and the way it does it is by using the id
as its mechanism for tracking.
I would not like to see this made optional for requests that require
responses.
best,
r
JSON-RPC is a protocol, not a transport. Many transports have a method
of associating requests with responses on their own.
I personally have never needed to use the "id" field, and my
implementations will return responses whether you specify an "id" field
or not, at least partially in the spirit of "be liberal in what you accept".
> I would not like to see this made optional for requests that require
> responses.
Why do you require an id field for requests that require responses in
your implementation? Why would the "notification: true" system not work
for you?
I'm assuming you aren't talking about batch requests here. Based on
the spec, it is completely permissible to request:
[
{"jsonrpc": "2.0", "method": "sum", "params": [2,4], "id": "1"},
{"jsonrpc": "2.0", "method": "email", "params": ['subject',
'message'], "id": "2"},
{"jsonrpc": "2.0", "method": "random", "id": "3"}
]
and receive:
[
{"jsonrpc": "2.0", "result": true, "id": "2"},
{"jsonrpc": "2.0", "result": 6, "id": "1"},
{"jsonrpc": "2.0", "result": 0.3577654, "id": "3"}
]
Without ids, that would look like:
[
{"jsonrpc": "2.0", "result": true},
{"jsonrpc": "2.0", "result": 6},
{"jsonrpc": "2.0", "result": 0.3577654}
]
I'm not sure how you would implement that without ids. (But I might be
missing something.) Now, obviously for a single request -> single
response in a shared-nothing environment, ids are not /as/ necessary,
but I still think they are intuitive and should be required for
optimum compatibility between implementations. Also, this keeps the
differences between single request and batch requests to a minimum,
which just makes the spec that much easier for people to pick up.
That's just my interpretation of the conversation, so apologies if
I've overlooked something.
Now notifications, those are a different argument (although there is
potentially impact on the id absence / requirement question.)
Josh Marshall
I'm not. I'm talking about single requests.
> I'm not sure how you would implement that without ids.
I agree--if you're going to do batch requests, you should probably add
ids, although I think that that should be up to the implementor--a
"SHOULD", not a "MUST".