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".
Not even a SHOULD, IMO.
In some cases, the actual data returned will be self-identificatory.
For instance, batch fetching a bunch of objects by ids, where those
ids found are returned as part of the object.
People are saying omitting the id reflects a transport bias that
doesn't belong in the spec; I see it the other way around;
requiring an "id":1 in so many cases where it is just plain
silly reflects a bias towards asynchronous socket transport.
Yes, we need to support id for many cases, but mandating it
in all cases to be "transport-neutral" isn't transport
neutral at all; it's support for one form of transport that
doesn't belong in the spec.
I read that paragraph and see it justifying one of the two purposes, not
explaining how they are really just one purpose. And I wasn't
questioning the need for both messages and calls.
> > A far more sensible arrangement would be a separate "notification"
> > parameter (defaulting to false if not present).
>
> I'm not sure it is, see the comment above. You keep linking the
> request object to the transport instance life time and suggesting
> optimizations based on that view. json-rpc is used in places where
> that is not true and there is little gained from the "optimization".
I think you are thinking of someone else. I'm not thinking of
optimization at all, just of making the spec fall more in line
with expectations of how people *will* use it.
> > This would then allow "id" to be optional, and to be omitted when the
> > client doesn't need it.
>
> The id *IS* optional, but the meaning implied by the absence of the
> field is different.
Yes, you either have to supply a (possibly meaningless to the client) id
or have it be treated as a notification, because the id field means both
"not a notification" and "the client needs this id returned" instead of
decoupling the two purposes into two fields.
> > 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.
>
> You are welcome to write it up as an extension specification, but it
> drastically changes the meaning of the request object based on
> contents and adds very little with the change, short of changing the
> meaning. I would imagine extensions with those sorts of
> characteristics are not likely to see much support/adoption by the
> community. We all want a simpler time of things, which is what draws
> many to json-rpc.
Agreed. But if you require spec changes to be vetted via an extension
first, you very much restrict the kind of spec changes that can be
proposed.
REST is resource oriented and expect that each resource a server can provide must be accessible through a URI
HTTP is meant to help building architecture with a REST style
what would be important with the support of the GET method by JSON-RPC is to respect the GET safety property
When doing a GET request on a server, no data should be modified on the server (only the log files ;-) )
Of course, as JSON RPC specify a representation format, the values of the jsonrpc parameter may be set in HTTP headers
ex:
Accept: application/rpc+json;version=2
(ok I'm pushing the MIME type I'd like to use...)
But I think it's ok to be able to fix it directly in the query string, as we already are used put a file extension in the URI
About the id, I agree I'd prefer be able to drop it to allow the cache
ex:
/rpc?$method=turnover&year=2009&month=12
Yes, you can see I experimented also other URI formats
I also agree params doesn't need base64 encoding by default
REST is resource oriented and expect that each resource a server can provide must be accessible through a URI
HTTP is meant to help building architecture with a REST style
what would be important with the support of the GET method by JSON-RPC is to respect the GET safety property
When doing a GET request on a server, no data should be modified on the server (only the log files ;-) )
Of course, as JSON RPC specify a representation format, the values of the jsonrpc parameter may be set in HTTP headers
ex:
Accept: application/rpc+json;version=2
(ok I'm pushing the MIME type I'd like to use...)
But I think it's ok to be able to fix it directly in the query string, as we already are used put a file extension in the URI
About the id, I agree I'd prefer be able to drop it to allow the cache
ex:
/rpc?$method=turnover&year=2009&month=12
Yes, you can see I experimented also other URI formats
I also agree params doesn't need base64 encoding by default
On Sep 6, 2010, at 12:45 PM, Max Kanat-Alexander wrote:
--
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.
I always have had a little trouble in uderstanding why a client should be allowed to specify in its call whether he wants an answer back or not. Is it not the
server/the function being called that determines the "message passing" vs. "function call" pattern?
- if the function being called has no meaningful return value, adding an id in the call merely forces the server to add a useless NULL response
- if the function being called has a return value, why would the client be able not want it?
A little off-topic: a question to implementors of http-based libraries: how do you implement management of the id field? Is it the duty of the user of the API
to provide an id, or does the library add an automatically generated one under the hood?
bye
Gaetano
Yes, you either have to supply a (possibly meaningless to the client) id or have it be treated as a notification,
because the id field means both "not a notification" and "the client needs this id returned" instead of decoupling the two purposes into two fields.
Agreed. But if you require spec changes to be vetted via an extension first, you very much restrict the kind of spec changes that can be proposed.
The current spec has almost four years maturation, it's status is currently "about to be ratified" for there is about nothing to be removed without breaking what's working, every word of it has been discussed, weighted and agreed on a very long period.
On Tue, Sep 7, 2010 at 14:31, Lorenzo Pastrana <past...@ultraflat.net> wrote:
The current spec has almost four years maturation, it's status is currently "about to be ratified" for there is about nothing to be removed without breaking what's working, every word of it has been discussed, weighted and agreed on a very long period.
Isn't this is a little bit like "we have already talked about these and whatever you say, we will not change it"?
JSON-RPC is forcing an asynchronous transport where as IMO it should be transport neutral.
There has been lots of activity bursts like this one in the elaboration of the specs and even some tense moments, but Matt could tell you : nothing has never been written down the document until the temperature has cooled, and an agreement was reached.
JSON-RPC is forcing an asynchronous transport where as IMO it should be transport neutral.JSON-RPC is forcing nothing on the transport, waiting for the server's response is perfectly OK if that's what you want/need, nothing prevents it in the current spec.
In the "protocol mind frame" the ID field just allows any transport to carry asynchronous calls AND batches.
"notification", please. "notify" is much more subject to being taken
exactly the wrong way.
> I agree with Yitzchak's point that it gives the id field a "double
> meaning", but I don't really see how that causes any issues. If you
> aren't going to use the id field to match responses.. fine, just pass
> "id=1" to every request. It's more compact that "notify=true"
> anyway :)
There are no implementation issues. The issues are social. By the spec
not allowing a client to specify "I want a response but don't need an
id", many people new to the spec will come here and ask why...or just
conclude that notifications are some poorly conceived bolted on thing
and just not support them...as the google poster has apparently done.
> This isn't something that I see as worth changing the specification
> over. No one has given a strong argument for why using the id field to
> indicate a response is desired limits functionality in any way on the
> client or the server. It may be "prettier" to have a separate
> notification field, but compact and simple work for me.
Certainly the 2.0 spec should not be changed. I, at least, am only
hoping to lay the groundwork for support for a change in a future
version.
slot is a transport-specific need (and even then, or in batch, is not
always needed). And that seems to cause some to not even conceive of
the obvious third case (and hence not see any dual-purpose).
> notification:false
>
> is not self sufficient, the server needs to refer to an ID for
> talk-back, if no ID is provided then the call must be assumed "not to
> be in a batch" AND hazardous assumptions are to be made on the
> synchronicity of the transport OR the call being just plain wrong ...
>
> In other words : a can of worms.
>
> As said previously the ID is needed in batches and provides the
> simplest pivotal point for any transport to be (possibly)
> asynchronous.
"needs", "needed": This is not true, or this discussion would never have
arisen.
Both of the JSON-RPC libraries on which I have worked operate as follows:
Client issues request, and caches information about the call in a table
(hash table, vector, JS object, what-have-you).
Client thread (or, in JS, an event handler) waits for response from
server. When a response arrives, the client library looks up the
JSON-RPC call in the table, using the id field in the response, and
issues it to the calling code.
The design of JSON-RPC seems clearly to assume (or at the very least
permit) such a client implementation, which will fail if id's are not
present.
FWIW, I think it's incumbent on you, as the person who wants to change
the existing spec, to explain to us why this is UNnecessary, instead of
asking us to demonstrate that it is necessary....
best,
r
I believe that the above reflects a misunderstanding of the function of
the id field. The id field is /not/ the identifier of some object or
other on the server. It is the identifier /of the request itself/. So
the above example really doesn't make sense. The id is part of the
JSON-RPC protocol itself; it is not visible to the server for other use
(e.g., to find an object).
I don't think the above is coherent. The id CANNOT be meaningless to
the client --- the client has, itself, provided the id. Indeed, it
doesn't seem to make sense to say that the server "supplies" the id.
The id is supplied by the client, and must simply make the round trip
through the server.
No, I have no misunderstanding. I was indeed talking about an id
supplied by the client but meaningless to the client, and, separately,
object ids supplied in the params of batched requests and returned in
the responses which obviate the need for the client to use the json-rpc
request id.
Shame it was called "id", not "request_id" or some such, but it's no
doubt too late to fight that fight (and the additional capitalization/
camel case/underscore battle).
This change looks the most "hard" to implement in generic jsonrpc clients (or the more specific one).Louis Ryan wrote: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.
CheersLouisJSON-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’
...
}
Could you not simply put that field as 1st (or last) element in the name of the functions themselves, eg: language.diacritize.get.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.
On Thu, 2010-09-02 at 20:19 -0700, Louis Ryan wrote:
Folks,
As announced at Google I/O were working on launching JSON-RPC support for most of our newer APIs.
Hi Louis, first of all that's great news :D
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.
That could sound, well ... conservative in your own case, but obviously implies that 2.0 is your default dialect for now, however there are a couple of points to be signaled :
JSON-RPC 2.0 has (wery few but some) antecedents in 1.0 :
>From the specs, 3 - Compatibility :
JSON-RPC 2.0 does not work with JSON-RPC 1.0 clients or servers.
[snip]it is easy to distinguish between the two versions as 2.0 always has a member named "jsonrpc" with a String value of "2.0" whereas 1.0 does not[snip]
The term "Compatibility" in that paragraph is intended "backward" and that's the only place where it was addressed (in an implicit way thus). Fact is that "the future's not ours to see" ... and neglecting that could turn in an unforeseen bullet heading slowly toward your foot ...
The jsonrpc member requirement is mostly intended for future compatibility, and future compatibility has been a strong concern all along the specs elaboration. Chances are that you'll be blessing that 10 bytes spent someday.
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.
I'd consider the cardinality of a batch being actually N - number_of_notifications
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.
If you do need any kind of validation / response, why do you omit the request ID in the first place ?
How an asynchronous client could ever dispatch a response without a request ID ?
Does anyone make significant use of the behavior described in the spec of perceive any performance advantage from it?
The main purpose of this kind of feature, as said Henry, is 'state change' notification ... A simple example would be a MMORPG where the client would periodically notify the server about it's player direction and speed so the server can compute collisions, encounters and so on.
When the player takes an action that could fail the client would use a request ID and hope for a response.
Error code alignment
See the thread running ...
apiVersion:
The specification doesn’t provide a mechanism for describing different versions on the same API.
Probably because JSON-RPC is a protocol, not an API :D
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’
...
}
This sounds to me like an "encapsulation error" but for communications, as if rails where to know if the train carried cargo or people ...
Why not :
{
id : ‘12345’,
method : “v2.language.diacritize.get”,
...
}
Or just a specific entry point ?
v2.some.api.server.google.com/call
{
id : ‘12345’,
method : “language.diacritize.get”,
...
}
Cheers,
Lorenzo
On Fri, Sep 3, 2010 at 6:56 AM, Lorenzo Pastrana <past...@ultraflat.net> wrote:
On Thu, 2010-09-02 at 20:19 -0700, Louis Ryan wrote:Hi Louis, first of all that's great news :D
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.
That could sound, well ... conservative in your own case, but obviously implies that 2.0 is your default dialect for now, however there are a couple of points to be signaled :
JSON-RPC 2.0 has (wery few but some) antecedents in 1.0 :
>From the specs, 3 - Compatibility :
JSON-RPC 2.0 does not work with JSON-RPC 1.0 clients or servers.
[snip]it is easy to distinguish between the two versions as 2.0 always has a member named "jsonrpc" with a String value of "2.0" whereas 1.0 does not[snip]
The term "Compatibility" in that paragraph is intended "backward" and that's the only place where it was addressed (in an implicit way thus). Fact is that "the future's not ours to see" ... and neglecting that could turn in an unforeseen bullet heading slowly toward your foot ...
The jsonrpc member requirement is mostly intended for future compatibility, and future compatibility has been a strong concern all along the specs elaboration. Chances are that you'll be blessing that 10 bytes spent someday.
I guess it is to avoid having a "version 1.0" server that is liberal in what it accepts responding to the version 2 client.
I've seen compactness used as an argument for the notification mechanism to cause response suppression and it is certainly a valid argument. In situations where there is an additional contract between the client and the server that is ex-protocol I think these kinds of optimizations are valid for low-bandwidth scenarios. In our case were clearly stating that we will not support JSON-RPC 1.0 or anything before 2.0 which I think is a reasonable stance to take.� I don't know to what extent other servers are relying on these value on input and output. In particular I'm curious about what dependencies people have on the output version. If the spec is requiring the value in the request and an id which is exactly correlateable to the produced response then what use is the version in the response? Is the expectation that I can make the call in 2.0 and get a response in 3.0 and if so to what end?
Okay, that sounds like a reasonable implementation. So, the id could
still be optional in the protocol--you just need one. If the client
didn't provide one, you could generate one and use it internally in your
library, right?
> FWIW, I think it's incumbent on you, as the person who wants to change
> the existing spec, to explain to us why this is UNnecessary, instead of
> asking us to demonstrate that it is necessary....
I never said that the "id" field is unnecessary, I simply said that it
should be optional, and that its optional-ness shouldn't imply something
else.
For an example of a disastrous overloading of a field in another
domain, look at the "autocomplete" attribute on HTML input fields.
There are many use cases for JSON-RPC. The "notification: true" system
would work in all of those use cases. However, I have demonstrated
several cases in this thread and other threads where the "id" field is
itself not necessary or is an inconvenience.
I'd really rather not see that done. The version is meta-data, and it's
a matter for the JSON-RPC library to be dealing with. The parameters
are things that the library should just be throwing down the tube to
whatever implements the function call.
If there's going to be metadata, I'd rather it be "on" the "envelope"
rather than "in" the envelope, if you know what I mean.
best,
r
> On Sep 7, 4:48 pm, Louis Ryan <lr...@google.com> wrote:
>> On Fri, Sep 3, 2010 at 6:56 AM, Lorenzo Pastrana <pastr...@ultraflat.net>wrote:
>>
>>
>>
>>
>>
>>> On Thu, 2010-09-02 at 20:19 -0700, Louis Ryan wrote:
>>
>>> Folks,
>>
>>> As announced at Google I/O<http://code.google.com/events/io/2010/sessions/how-google-builds-apis...>were working on launching JSON-RPC support for most of our newer APIs.
>>
>>> Hi Louis, first of all that's great news :D
>>
>>> 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
>>> *Absence of �id� to indicate that no response should be produced*
>>> *apiVersion:* The specification doesn�t provide a mechanism for
>>> describing different versions on the same API.
>>
>>> Probably because JSON-RPC is a protocol, not an API :D
>>
>>> 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�
>>> ...
>>> }
>>
>>> This sounds to me like an "encapsulation error" but for communications, as
>>> if rails where to know if the train carried cargo or people ...
>>
>>> Why not :
>>
>>> {
>>> id : �12345�,
>>> method : �v2.language.diacritize.get�,
>>> ...
>>> }
>>
>>> Or just a specific entry point ?
>>
>>> v2.some.api.server.google.com/call
>>
>> See my earlier comment for some context on this. There are some expectations
>> that we need to meet that make this an interesting choice.
>>
>> - People are used to version names with dots in them which makes them a poor
>> choice for valid Javascript identifiers.
>> - We have more than one API under the same namespace with different versions
>> which while not strictly a problem may cause user confusion
>>
>> language.diacritize.v2.get
>> language.translate.v3.get
>>
>> as we cant guarantee that the version if the first literal value in the
>> identifier. This is something we may address by other means in our client so
>> I'm not ruling this out.
>>
>>
>>
>>
>>
>>> {
>>> id : �12345�,
>>> method : �language.diacritize.get�,
Yeah, agreed. I don't think it would be good for systems to have to
parse and access the parameters before calling the function specified in
"method".
> There is no such thing as dual-purpose on the ID field : > > the unique meaning of the ID field is whether the client is listening > or not for a response. > > - ID : "I'm listening on ID slot" > - no ID : "I'm not listening" slot is a transport-specific need
My feeling is this discussion arose because someone got the full picture out of sight, and especially in this case got confused between runtime ID "need" or lack of, and the specification needs.(and even then, or in batch, is not always needed). And that seems to cause some to not even conceive of the obvious third case (and hence not see any dual-purpose). > As said previously the ID is needed in batches and provides the > simplest pivotal point for any transport to be (possibly) > asynchronous. "needs", "needed": This is not true, or this discussion would never have arisen.
FWIW, I think it's incumbent on you, as the person who wants to change
the existing spec, to explain to us why this is UNnecessary, instead of
asking us to demonstrate that it is necessary....
When you issue a single request in XHR for instance you use the functional callback mechanism in JS to correlate the response with the call so the id is superfluous in this case. We can always have our client produce a synthetic one which has no meaning so it's not a big deal its just for the overwhelming majority of our expected traffic its not needed.
Hey Lo.
So, broadly, there are two types of calls:
A) Batch (usually requires ids)
B) Single (sometimes does not require ids)
There are two types of timing:
C) Asynchronous (often requires ids)
D) Synchronous (usually does not require ids)
There are (for the sake of this discussion), two types of transport:
E) A transport which tracks which response is associated with which
request. (does not require ids for single calls, may require them for
batch calls [see below])
F) A transport that does not track which response is associated with
which request. (requires ids for all calls)
And there are two types of batch handling:
G) Returning responses in the same order as the request. (does not
inherently require ids, unless one of the requests is a notification)
H) Returning responses in a random order. (requires ids)
As could be worked out by analyzing the above, there are many valid
combinations above that do not require ids for proper functionality.
There are also many valid combinations above that *do* require ids.
Since there are some combinations that require the id field and some
combinations that do not require the id field, it would make sense to
simply make the id field optional. That way, the conditions that *do*
require an id field (which will be known by API consumers at development
time) can use the id field, and the conditions that don't require an id
field don't have to use it.
Right. But this might in some cases be more hair than it's worth,
because if the server is implemented in a dynamic language like
JavaScript, the mapping might change, and you would have to have logic
to invalidate the cache...
>
> You could also make the method raw json and have it decoded, but I
> would like to see the behavior well spelled out before even
> considering changing the specification to allow a complex path object
> instead of a marked up path string. I do something like this in
> another area of our software(s) and despite being a little non-
> traditional, it reads like a DSL for complex path based method
> selection.
I'd be reluctant to have the method have decoding applied, because to me
one of the big advantages of the JSON-RPC spec is that it is good for
/cross-language/ RPC. Assigning a semantics to the method name string
seems dodgy because it would impose more constraints on the server
implementation. As I understand things now, the only requirement on the
server is that it somehow translate the method [I wish this were
"procedure," FWIW, since there is no sense in which this is a method,
except possibly a method of the server...] name into a procedure to be
called.
Currently, if the server wishes to interpret the "." as some kind of
scoping or method application operator, there's nothing to stop it, is
there? So it seems like the above suggestion would just impose costs on
compliant servers without providing added function.
Perhaps I'm missing something, but if so, that might be a sign that this
suggestion needs unpacking.
Best,
r
If the client didn't provide one, you could generate one and use it internally in your library, right?
Only the client knows what the ID is for, the server only echoes it for the client to dispatch responses.
I never said that the "id" field is unnecessary, I simply said that it should be optional
I have demonstrated several cases
The "notification: true" system would
I don't believe that is a correct understanding of Max's argument.
The JSON-RPC spec is handling the case of client library to server
library communication. It doesn't (nor should it) have anything to say
about what API the client library exposes to calling code, nor does it
say anything about how the server library calls methods on the server.
Those are all outside scope.
So if the client library is always going to supply id's, then we should
just keep the mandatory id's in the spec.
It's only if the /client library/, not the calling code, can do without
the id's that we should consider dropping them.
Max's argument relies on the fact that there are client /library/ cases
where there is something about the transport layer which means that
responses will never appear out of order. That is why he argues for the
id being optional in cases where there will be responses.
best,
r
That's what I was trying to say; that the client library's interface
would not expose id at all, and the client library would generate and
use one for those cases where one was needed but otherwise shouldn't
have to.
Though due to json-rpc's simplicity, I think many of the users in
cases where an id isn't needed won't be using a json-rpc library
at all.
--
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.
Max,
I know you are pushing for making the id optional, but that only works
when you pass that responsibility onto the transport/transport
instance, and that makes a lot of strong assumptions which often are
not true for other usage patterns.
Granted, 80% of the json-rpc calls I make probably do not need an id
with the view you are holding, but allowing the id to be optional
complicates the other meaning that a lack of id currently represents.
Your solution to this is by adding that meaning in again via another
field. This is an change/optimization that is heavily weighed towards
non-notifications, and a lot of change to get there for little gain.
I am not seeing the complication in always sending an {id:""} if your
-API versions:
I don't really see a need to embed version information at the
individual request level. If you want to have multiple versions of a
method available on the same endpoint, using method names with
versions seems reasonable, however I generally prefer the approach of
giving each version of the API it's own endpoint, which is the
approach used by most web services these days. Given that there is no
concept of "api versions" defined or described in the spec, I think
it's a rather heavyweight concept to add just to allow multiple method
signatures with the same name (which is the net result of your
suggestion).
-Dave
Hey Matt. :-) Thanks for taking the time to respond. :-)
I don't mean to be pedantic, but what do you mean by "strong
assumption" there? When I read "strong assumption", I tend to interpret
it as meaning, "makes an assumption which must always be true in all cases."
> Granted, 80% of the json-rpc calls I make probably do not need an id
> with the view you are holding, but allowing the id to be optional
> complicates the other meaning that a lack of id currently represents.
> Your solution to this is by adding that meaning in again via another
> field. This is an change/optimization that is heavily weighed towards
> non-notifications, and a lot of change to get there for little gain.
So far, 100% of the JSON-RPC calls I've made haven't needed the id, and
you said above that 80% of yours probably didn't.
It's true that making the id optional complicates the second meaning
that the id represents, which is why I'm suggesting that the id field
should be disambiguated. Disambiguation is good for any protocol or system.
It is indeed heavily weighted toward non-notifications, but I think
that JSON-RPC should in fact be weighted toward non-notifications. In
fact, I think that notifications themselves should have been an
extension spec, and they should not have been a part of the core. One of
the primary reasons that I say that is that I'd estimate that less than
1% of all JSON-RPC traffic currently being generated in the world uses
the notification mechanism, and the vast, vast majority of JSON-RPC
calls are not, in fact, notifications. In fact, I'd guess that the vast
majority of API implementations don't even need the notification
functionality.
> I am not seeing the complication in always sending an {id:""} if your
> framework/transport is going to handle the context for you anyway and
> you just don't want to deal with it directly.
It's not a complexity for *me* that I'm trying to eliminate. I'm an API
implementer and library implementer. The existence or non-existence of
the id field makes no difference to me (except that library
implementation is ever-so-slightly simpler if you don't have to worry
about notifications).
What I'm trying to do is make life easier for consumers, who will
frequently not understand why they have to send an "id" field simply to
get a response, when they thought that they were making a remote
procedure call that would give them some data. "After all, the API docs
say that the function returns data--so why doesn't it return data to
me?" It's the sort of thing that people can spend hours on. I can
promise you that this will be an issue of confusion and frustration for
the many API consumers who have not read through the JSON-RPC spec, and
who, I think, shouldn't have to read through the protocol spec just to
interact with an API.
It's particularly frustrating, as I've mentioned above, in an HTTP GET
situation, although we could certainly mitigate that by making the id
optional *in HTTP GET*. Of course, then you couldn't do notifications
via HTTP GET.
None of this would be a problem if notifications were an extension and
had an unambiguous second field. It could even be called "n" if people
were worried about length.
what do you mean by "strong assumption" there? When I read "strong assumption", I tend to interpret it as meaning, "makes an assumption which must always be true in all cases."
It's true that making the id optional complicates the second meaning that the id represents, which is why I'm suggesting that the id field should be disambiguated. Disambiguation is good for any protocol or system.
Max, please read again :
It is indeed heavily weighted toward non-notifications, but I think that JSON-RPC should in fact be weighted toward non-notifications.
the id field makes no difference to me
except that library implementation is ever-so-slightly simpler if you don't have to worry about notifications
On Wed, 2010-09-08 at 18:32 -0700, Max Kanat-Alexander wrote:"strong assumption" means that reality could, and certainly will, be different.what do you mean by "strong assumption" there? When I read "strong assumption", I tend to interpret it as meaning, "makes an assumption which must always be true in all cases."It's true that making the id optional complicates the second meaning that the id represents, which is why I'm suggesting that the id field should be disambiguated. Disambiguation is good for any protocol or system.Max, please read again :There is no such thing as dual-purpose on the ID field :
the unique meaning of the ID field is whether the client is listening or not for a response.
- ID : "I'm listening on ID slot"
- no ID : "I'm not listening"
There is actually no need to decouple this bit because both behaviors are mutually exclusive,
This field setup is coupled to an algorithm which is absolutely simple :Why ? Notifications exist and their existence is legitimate.
It is indeed heavily weighted toward non-notifications, but I think that JSON-RPC should in fact be weighted toward non-notifications.
You, as an individual, represent 0,0000000145% of the world population, you still have a legitimate existence and a hole bunch of rights.
Nobody can force you to conform to the spec, as well as you cant ask the spec to be restricted to your own specific need because you can't miss what you can't figure.... what's the point then ?the id field makes no difference to meThat's false because notification won't disappear. Using more than the id field will complicate clients AND servers by orders of magnitude.except that library implementation is ever-so-slightly simpler if you don't have to worry about notifications
If you disagree, instead of asserting in the vague, please be specific and provide complete solution that doesn't rely on negating needs you just don't have in your specific case, and provide algorithmic details (see model below).
If you don't, we will just consider the ID question closed for lack of motive.
[quote][/quote]
In addition a protocol is not just data, it implies an algorithmic aspect (which is certainly not explicit enough in the spec).
When someone has a pattern that would allow optional ids and would make no assumption on transport, or single call situation, doesn't break notifications, doesn't add ambiguities or under defined zones, has no meaning overlap, fits well in the actual spec (doesn't require to mess everything up), and that can compete with the simplicity of :
Client side :
call_rpc(endpoint,method,params,done)
{
id = new_id();
slots[id] = done;
transport_rpc(endpoint,call,id);
}
Server side :
process_rpc(call)
{
result = execute_call(call.method,call.params);
if(is_defined(call.id))
{
writeout_response(call.id,result);
}
}
Client side
dispatch_response(res)
{
if(is_defined(slots[res.id]))
{
slots[res.id](res);
}
}
Let us know.
--
On Sep 9, 1:48 pm, Louis Ryan <lr...@google.com> wrote:
> On Thu, Sep 9, 2010 at 3:11 AM, Lorenzo Pastrana <pastr...@ultraflat.net>wrote:
> [...]
> why should Matt's behavior be favored over Max's. Again, if the spec isWell, for starters "Matt's behavior" matches the existing spec. :)
> final then this is a moot point, if not then lets find out what people are
> doing.
I do not see it as choice between the two, my example is just a
counter-example to why what Max is suggesting should not be the
default behavior. Confusing as some folks might find it.
From my point of view the 2.0 spec is basically final, minus
clarifications or clear errors in the document itself. I am guessing a
lot of others who have been involved with this for a while view it
that way also. That will at least allow us to keep 2.0 as a reference
point in time, just as 1.0, 1.1WD, and 1.1ALT.
If later versions of the specification come out through the community
and bubble up, then at least those of us only desiring 2.0 have a
strong reference point/version number should we decide to stay behind
or use different future extensions. Just like those who only support
json-rpc 1.0 today.
I am hoping Max will start a new thread to discuss his proposal to
remove the id and add a notification flag, especially as it relates to
HTTP GET. Solidify it into an extension specification so we can all
try it out and see the reality it provides. If json-rpc 2.0 +
optional_id_by_default works out, perhaps that will become the next
version of json-rpc. Perhaps it will stay an extension specification,
perhaps it will lead to lots of other better thoughts, but the best
way to address this is to `cook and taste it` and then decide.
--
Matt (MPCM)
That sounds like a great idea. :-) Will do (although I'm not sure I'll
get to it today).
> I generally agree with Max that the overwhelming majority of use will
> be synchronous HTTP
JSON-RPC was born as a general purpose RPC protocol, and I do hope it
will stay off HTTP predicates.
> Matt's example server which enqueues responses on the server for
> asynchronous delivery to the client across connection issues is a good
> example of why id's are important,
This is why I believe as well as may others that the ID field is
legitimate and necessary, and the spec rather mature on that point. I
must say, even if I didn't took part for now that the thread on errors
n� vs name is much more constructive than this one, however :
> Why should Matt's behavior be favored over Max's.
Because unfortunately Max's proposal (until now) is
very biased toward a particular transport
adds complexity instead of clarifying the spec
makes assumptions that won't be always verified
brakes some cool features of the protocol
but most of all is really incomplete ...
While Matt, me and some others have worked for long on the current spec
and just agrees with it as it is.
> Again, if the spec is final then this is a moot point, if not then
> lets find out what people are doing.
This is why I invited Max or anybody that can come with a clever idea (I
don't have a monopoly upon) to be completely specific and propose a
modification that is mature on all aspects instead of poking around
assertions that are based on the the following terms : Lots of , Most,
Usually, Certain, vast majority etc ...
My point was about the method, not the object.
Additionally I just wanted to clarify what he was about to modify to
make sure the current spec is well understood.
Lo.
Absolutely. I'd love to see the current version of the 2.0 spec
marked as final. Even though I personally support the idea of string
based errors rather than numeric error codes, I think the current spec
has been well tested and has a number of implementations behind it,
and that changes should happen either as an extension or a new
version.
Cheers,
Rasjid.
I think this is a great explanation, and should probably be written up
somewhere, or even added to the spec as a description of the purpose
of the id field.
In a few lines it explains clearly:
* why no id (ie, a notification) means the server should not send any
response (the client is not listening), and
* why if you don't "care" about the id field, just sending id: 1 for a
request is completely valid (you are saying that the client is always
listening on slot 1)
Cheers,
Rasjid.
On 9 September 2010 20:11, Lorenzo Pastrana <past...@ultraflat.net> wrote: > There is no such thing as dual-purpose on the ID field : > > the unique meaning of the ID field is whether the client is listening or not > for a response. > > - ID : "I'm listening on ID slot" > - no ID : "I'm not listening" > > There is actually no need to decouple this bit because both behaviors are > mutually exclusive, I think this is a great explanation, and should probably be written up somewhere, or even added to the spec as a description of the purpose of the id field.
Design rationale annotations might be a nice addition to the
specification. I have in mind something where the annotations are kept
easily accessible, but not merged into the spec, so that the spec can be
read without them, or with them.
E.g., an arrangement where the spec can be read online in its unadorned
form, or read in a frames arrangement where the annotations are located
in a frame adjacent to the spec statement. That would be really neat.
best,
r
> What I'm trying to do is make life easier for consumers, who will
> frequently not understand why they have to send an "id" field simply to
> get a response, when they thought that they were making a remote
> procedure call that would give them some data. "After all, the API docs
> say that the function returns data--so why doesn't it return data to
> me?" It's the sort of thing that people can spend hours on. I can
> promise you that this will be an issue of confusion and frustration for
> the many API consumers who have not read through the JSON-RPC spec, and
> who, I think, shouldn't have to read through the protocol spec just to
> interact with an API.
>
I'm afraid I /still/ don't get this point. Why does the consumer ever
have to even know that there is an id field? Shouldn't the client
library be making the JSON-RPC object for the consumer, and then
unwrapping the response object and presenting the consumer with the result?
This point about the consumer recurs, and I feel bad saying this, but it
seems like this will only happen if the JSON-RPC mechanism is
implemented in a way that inappropriately exposes the transport details.
I know it seems rude to say this, but it seems that if a consumer needs
to read the JSON-RPC spec to use an API through a client library, then
that client library is busted, and the consumer should find a different
one. The library should /always/ hide the JSON-RPC object from the
consumer.
Now, if the client library is hiding the JSON-RPC object from the
consumer, then it's really no big deal to have the client library comply
with the requirement for an id. Indeed, arguably it would be /more/
complicated to have the client library worry about whether to add it or
not....
I suppose if you are building a client library that you know is always
going to be operating with synchronous responses, then you might want to
write that library to never have the id. But really, is it /that/
painful to just put an incrementing integer counter into the id field?
FWIW, the reason I like JSON-RPC is that it provides a nice RPC protocol
over sockets. Whatever the advantages/disadvantages, I can live with
AJAX or the equivalent using JSON. So the big win in JSON-RPC for me is
that it lets me use other transport protocols without having to eat an
elephant like SOAP or CORBA....
Best,
r
For better or worse, the JSON-RPC spec suffers from the flaw that many
clients or servers will not use a separate json-rpc library layer
because it's so d*mn simple.
> I know it seems rude to say this, but it seems that if a consumer needs
> to read the JSON-RPC spec to use an API through a client library, then
> that client library is busted, and the consumer should find a different
> one. The library should /always/ hide the JSON-RPC object from the
> consumer.
That seems inconsistent. Take a hypothetical API using HTTP. Either
the API documentation will just say "uses JSON-RPC" and then refer to
"error", "params", "result", etc. where needed (in which case a client
will need to read the JSON-RPC spec to know what that means) or the API
documentation will include full examples of JSON-RPC requests and
responses and have to explain why "id" is needed even though this is
synchronous transport.
Unless you are proposing that an HTTP-based API designer go and find and
test json-rpc libraries to suggest people use for every possible client
language? That's a never-ending task, even if such libraries existed
for more than a fraction of the possible client languages.
I'm completely mystified what it is you expect API documentation to tell
the prospective consumer.
What I have implemented so far on the server-side is:
. the server passes to user-code function a 'request' object, where the incoming id is available if the end-user code wants to inspect it
. user-code function returns a 'response' object, where id is not needed. Server injects original id in the response while serializing it
. what if the user-code function returns a 'response' object where the id has been changed from the received one? So far this is not handled at all (ie. id will
be overwritten with the server's one)
On the client side:
. the user-code needs to pass to the 'client' obj a 'request' obj. The id field has to be managed by user-code (currently passed as param to the constructor to
the 'request')
advantage: in case the server needs specific IDs, user-code can use them
disadvantage: user-code needs to always manage those pesky ids by itself
An evolution could be to hide management of ids from the client-side user code, too: either by creating a getnewid() method that would return a unique id every
time, or by removing the id from the constructor of the the 'request' obj and making it completely transparent to user-code.
Q1: is any real-life server using IDs which have a specific meaning / format and would not work if every request received was an increasing integer number?
Q2: what approach has been chosen so far by other implementors?
Keep in mind that having a library API that is compatible with spec version 1.0 is considered a bonus in my case.
Bye
Gaetano
So far as I've heard, people are universally *never* using the json-rpc
id for anything that would "have a specific meaning" to the user code
on the server or on the client.
I think you are making things much more complicated than they need to be
by trying to support that. If an id is meaningful to the remote
procedure, it belongs in the params object. If an id is meaningful to
the client-side user code, it belongs in the result or error object.