JSON-RPC 2.0 Batch Discussion

798 views
Skip to first unread message

Matt (MPCM)

unread,
Jun 10, 2009, 8:25:25 AM6/10/09
to JSON-RPC
Batch being in 2.0 has sparked a bunch of conversations. This thread
is here to keep those discussions separate from the main spec thread
for the moment. Hopefully the understand we reach here can be applied
into the primary spec.

Traditionally json-rpc did not include batch/multi-call, as we had a
lot of discussion and differing points of view when this came up years
ago. I'm trying to summarize, so please correct/update this post if I
am misrepresenting or under representing other views.

The current 2.0 suggests handling batch as an array of request and
that it should return an array of responses. This of course had
generated questions like:
* how to handle notifications
* order in which to process
* order in which to return

My take on where agreement has been reached is that requests do not
need to be processed in order (any order). This should allow parallel
processing of requests. There is a view that should be returned in the
order they came in, minus notifications. I am of the view that no
required return order is of greater benefit long term.

I am going to step out on a limb a little and suggest that if we had
concurrent/streaming json-rpc servers, the least restrictions is of
the most benefit. Instead of handling a group of requests as a fixed
known array, if it could be viewed that the first [ of the request
array is in essence opening a connection to the server, the server
could read and process each request, separated by a "," until a
closing ] is sent. The response would immediately send back a [,
followed by response objects, separated by a ",", until the closing ]
is sent. This is why I would prefer to not see order required, as it
would require more buffering and delaying the communication of
finished work.

This streaming concept isn't happening today and current transport
implementations do not easily represent this model. Doing the
streaming/concurrent thing requires some other changes, and has it's
own nuances. I always view least restrictions as the best path forward
for those of us looking to push the limits, while staying close to the
specs.

Order of the responses is something I am not really stuck on, I would
just prefer if it was not required. If you only deal in known fixed
array blocks and processed sequentially, order makes more sense.
Seeing as most users are unlikely to use batch heavily, my imaginary
streaming servers are even less likely ( at least for the next year or
two). ; )

Just wanted to share where I was coming from on the order thing.

--
Matt (MPCM)

Brian

unread,
Jun 11, 2009, 6:40:57 PM6/11/09
to JSON-RPC
I think there are benefits to ensuring that the order in which batch
calls are are processed is guaranteed. Imagine a scenario like this:

CreateSpreadSheet()
AddColumn("first name")
AddColumn("last name")
AddColumn("age")
AddRow("bob", "villa", 99)
AddRow("jon", "smith", 15)
FinishSpreadSheet()

There is an obvious state that's maintained through each of the calls.
And in the case of JSON-RPC over HTTP this is an extremely beneficial
feature - 1 HTTP request vs. 7. Of course this "state" raises all
kinds of issues related to transaction management (ie: if call 3 fails
you wouldn't want the rest of them to be processed).

Hmm, maybe I'm over complicating it.

With all of that said - if state isn't preserved and each call in the
batch is treated like a new call then state is of no concern and the
calls could theoretically be processed in any order.

Matt (MPCM)

unread,
Jun 12, 2009, 12:18:21 AM6/12/09
to JSON-RPC
I agree that having this ability to chain calls is of great benefit.
Just that this should not be what batch "is". Perhaps something `set
processing` is a better term instead of batch (?).

Your example is a good example. Your API looks like you are inside the
object instance, abstractly. You are creating an object, then invoking
methods, adding data, then saving or returning it. But unless your
json-rpc server is mapped directly to that object / object instance,
you'll need to pass a state identifier of some kind.

Which would make your example look more like:

CreateSpreadSheet() //returns an id
AddColumn(id,"first name")
AddColumn(id,"last name")
AddColumn(id,"age")
AddRow(id,"bob", "villa", 99)
AddRow(id,"jon", "smith", 15)
FinishSpreadSheet(id) //saves or returns spread sheet (?)

=========================================
A separate point, but this could also easily be done in one fell swoop
with a call that performs the manual calls itself based on input.
GenerateSpreadSheet(["first name","last name","age"], [["bob",
"villa", 99],["jon", "smith", 15]])
=========================================

But the issue of establishing "failure" is the sticking point. How do
you determine failure? Anything true, anything false, any error, any
truthy return, any falsy return? Perhaps you want a mix? Perhaps you
really need logic branches... this is why I think the 'bag of
requests' returns 'bag of responses' is such a cleaner and more
reasonable expectation. `Stepped Sequential batch` is really only a
specific subset, though probably a commonly desired usage pattern.

Your example is really several concepts. A set of actions, an implied
order chain, and a set of expectations under which to continue down
the provided order chain. I have some systems that work like this, but
I only use them on one end of the json-rpc mechanism or the other, not
across it. It's basically distributed processing/programming in a DSL/
json micro-format. It works, but it's not for the faint of heart...

I am mostly thinking (posting) out loud on the subject... what are
other's doing to handle batch or other similar implied logic order
tasks? Are you adjusting your API's or taking other approaches? Any
real world examples where this is or isn't an issue for your current
usage?

--
Matt (MPCM)

Brian

unread,
Jun 12, 2009, 12:02:13 PM6/12/09
to JSON-RPC

The API example I gave could most definitely be "fixed" in a batch mode
(without state) where you pass state around with every invocation.
The point i was trying to make is that batch processing could be very
complex to implement if it had to maintain state (although probably
easier over HTTP). And there would need to be some sort of
transactional concept. I just think it may be more than what is
necessary.

I agree that batch mode should merely be multiple calls in a single
request that would normally have to be sent across multiple requests.
And the return is multiple responses in any order. This has obviously
huge benefits when used over HTTP especially (single HTTP request vs.
many). To me, returning them in order implies that there may be some
sort of state mechanism (at least it feels like it).

With that said - when i implement batch processing for spring-jsonrpc
it'll probably execute them in order and return them in order - at
least to start :)

Brian

unread,
Jun 25, 2009, 2:44:38 PM6/25/09
to JSON-RPC
I added batch support to jsonrpc4j - it executes them in order and
therefore returns them in the same order.

Roland Koebler

unread,
Jun 27, 2009, 10:36:50 AM6/27/09
to json...@googlegroups.com
hi,

@Matt: thanks for your summary.

> The current 2.0 suggests handling batch as an array of request and
> that it should return an array of responses. This of course had
> generated questions like:
> * how to handle notifications

Notifications should be omitted IMHO in the response; The only
question is: What should happen if the multicall only contains
notifications?
Should (a) an empty array be returned, or (b) no response sent at all?

> * order in which to process
> * order in which to return

I think we will have two different kinds of "multicall":
- A very simple multicall, which cannot be configured, and is mainly
intended for reducing overhead. This is the thing called "Batch"
in the JSON-RPC 2.0 draft.
- A more complex multicall, which can be configured.
This could be done by an extension, where the behaviour could be
configured with some parameters, e.g.:
rpc.multicall([list-of-calls], abort_on_error, process_in_order, pass_result_to_next_call, ...)

Further functionality, like transactional behaviour, "atomic multicalls",
rollbacks etc. are outside of the scope of a RPC-system.


So, I would keep the "Batch" simple, meaning:
- no processing order,
since (a) multiple calls in one Batch which depend on each other
don't belong to the "simple" multicall; and (b) processing several
requests in parallel may really speed things up
- return in the same order as in the call,
since then the client doesn't need to sort the responses

> I am of the view that no
> required return order is of greater benefit long term.

I don't see any benefit of "returning out of order" -- even if we had
streaming JSON-RPC servers -- because:
- With a simple client, the client would always wait for the complete
multicall-response before it processes the responses and continues.
Here, returning the responses in order is better, since the client
doesn't need to sort the responses or use the id to determine to
which call the response belongs.
- So, "returning out of order" could only be useful if the "client" can
handle the responses independently, i.e. only if there are several
independent parts (e.g. threads) in the client. But then, it would
be better/simpler in my opinion, if every independent part communicates
independently with the RPC-server.


regards,
Roland

Matt (MPCM)

unread,
Jun 27, 2009, 9:16:08 PM6/27/09
to JSON-RPC
Completely agree with the keeping it simple, and defining batch as you
have. Complexity is best left out, unless there is proof of the value
of considering it. That's were extensions come in handy.

I agree a streaming server without a streaming client offers no real
advantage with out-of-order, the no implied order in processing is the
important bit.

I am still not sure of the real value in replying in the same order
for client side sorting, as the code is going to handle the matching/
callback anyway.

The "out-of-order" return is not something I am too stuck on. Simple
batch is an ideal I'm happy with.

A summary of my current thoughts:
*No implied order in processing.
*Same-as-sent order in replying
*Notifications are omitted.
*all notification batches should return an empty array
**servers can optimize here and bail really early if they know there
are only notifications


--
Matt (MPCM)

Lorenzo Pastrana

unread,
Jun 29, 2009, 7:16:30 AM6/29/09
to json...@googlegroups.com
On Sat, 2009-06-27 at 16:36 +0200, Roland Koebler wrote:
> So, I would keep the "Batch" simple, meaning:
> - no processing order,
> since (a) multiple calls in one Batch which depend on each other
> don't belong to the "simple" multicall; and (b) processing several
> requests in parallel may really speed things up
> - return in the same order as in the call,
> since then the client doesn't need to sort the responses

I would opine for no-order in AND no-order out, since that's what
request id's are for ... And that come with maximum flexibility and most
use-case flexibility.

Regards,
Lorenzo.


Gaetano Giunta

unread,
Jun 29, 2009, 8:04:33 AM6/29/09
to json...@googlegroups.com
Lorenzo Pastrana a écrit :
+1
Regards,
Lorenzo.





  

Matt (MPCM)

unread,
Jul 2, 2009, 11:24:13 AM7/2/09
to JSON-RPC
The argument that order needs to be kept upon return implies that the
structure to handle returns on the client is linked to the order they
went in, in a way that does not rely on id's...

I was thinking that a simple client would have a set of calls and
corresponding callback functions, where the calls get packed into an
array and sent, the id's are saved with the callbacks for that set,
then upon the return for that set, the callbacks are triggered in
whatever order the client processes them. (forwards, backwards, etc...
sideways ;) ).

Could you explain the client usage pattern where keeping returns in
order is more appealing?

Are you seeing a single, but more complicated set handling callback?

--
Matt (MPCM)

Lorenzo Pastrana

unread,
Jul 2, 2009, 1:12:14 PM7/2/09
to json...@googlegroups.com
On Thu, 2009-07-02 at 08:24 -0700, Matt (MPCM) wrote:
> I was thinking that a simple client would have a set of calls and
> corresponding callback functions, where the calls get packed into an
> array and sent, the id's are saved with the callbacks for that set,
> then upon the return for that set, the callbacks are triggered in
> whatever order the client processes them. (forwards, backwards, etc...
> sideways ;) ).
+1
Actually, I can't think of a simpler way (provided that calls are
batched) to implement any option (order or not)

Lo.

Matt (MPCM)

unread,
Jul 21, 2009, 1:09:54 PM7/21/09
to JSON-RPC
The only part we seem to disagree on is the order of response matching
the order of request. What would be the best way to move this
discussion forward?

@Roland:
Is this something that we can agree to implement now without an
implied return order?
Should it turn out to make more sense with an implied order we can
consider adding that restriction in for a later spec revision?

That way 2.0 clients that use id's to handle responses would work with
any later revision that might also require that order be preserved.
Doing it in the reverse order would cause that not be true.

--
Matt (MPCM)

Matt (MPCM)

unread,
Aug 21, 2009, 1:54:53 PM8/21/09
to JSON-RPC
I'd like to take a vote on this at some point, so we can finalize 2.0
(again) and close out this part of the discussion. I have not heard
back from Roland and have attempted to contact him via email off the
list. He was the only objection as far as I could tell...

Does anyone have any methods of contacting him, or could attempt to
contact him via email?

Does anyone object to having no specified order for processing or
matching return order in batch operations?

--
Matt (MPCM)

Brian Dilley

unread,
Aug 24, 2009, 8:44:35 PM8/24/09
to json...@googlegroups.com
I'm fine with it not coming back in order

Lorenzo Pastrana

unread,
Sep 1, 2009, 7:25:26 AM9/1/09
to json...@googlegroups.com
+1 that make sense.

Omi

unread,
Sep 2, 2009, 6:52:54 AM9/2/09
to JSON-RPC
Couldn't ordered batch requests be handled using the current spec by
using something like

BatchRequest( [

Request1,
Request2,
....
RequestN ] )

where Request[n] is a JSON-RPC method call

where the method BatchRequest handles all the requests as one.

With multiple servers, sending individual requests albeit tagged
cannot be guaranteed to all run on the same server and might not be
aware of each other which can be achieved with the current spec.

Matt (MPCM)

unread,
Sep 2, 2009, 10:15:53 AM9/2/09
to JSON-RPC
Yes. I have a few methods that take in sets of parameters and just
loop through them, calling the singular version of the method.

(i.e.)
sums(a) and sum(b,c)
where b and c are numbers to be added
where a is an array of pairs to be added, and it just calls sum(a[i]
[0],a[i][1]) inside a loop over a.

Others have implemented multi-call in the past where the param is a
lists of json-rpc request objects to get marshaled. A request object
full of request objects.

Order, sequence, continue-on-error and fail-on-error choices then
become method/API specific, which I believe is where those sorts of
issues should be living.

This 2.0 version called batch is simply a way of shipping those
requests to the server as an array (instead of inside a request
object), and thus doesn't require any meta-json-rpc double layering
stuff. The server can tell early on that this would be invalid to a
1.0 system and clearly not a regular request call, so the splitting
can be done upfront rather than in a special method already inside a
'being processed' request call.

At least for me, the feedback here suggests that no implied order in
processing and no implied order return has broad support. I'm going to
take this as my understanding of 2.0 batch, and we can move to enter
it into the specification document as such. Hopefully Roland won't
object too much when (if) he returns.

I'm still cleaning up my jsonrpc 2.0 php implementation, but it now
supports batch calls and it randomizes the processing order, to make
the point. Consists of two classes, the json-rpc server (77 LOC) and
the http_transport wrapper (52 LOC).

--
Matt (MPCM)

Alexandre Morgaut

unread,
Sep 4, 2009, 8:04:21 AM9/4/09
to JSON-RPC
+1
actual batch definition is as simple as we could hope
its good to preserve it from required ordering

To reply about implementing a parallel advanced batch support,
I thank about things like that :

Batched Call:

--> {"jsonrpc": "2.1", "id": "10", "sequential": true, "transaction":
true,
"batch": [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4],
"id": "1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params":
[7]},
{"jsonrpc": "2.0", "method": "subtract", "params":
[42,23], "id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get", "params":
{"name": "myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"} ]}

<-- {"jsonrpc": "2.1", "id": "10", "error": {"code": -32600,
"message": "Invalid Request."}, "id": null} "batch": []}


with option:

"sequential": true if the procedure have to be process sequentially in
the received order

"stopOnError": true to stop the batch on first error. only the first
procedure have been processed (not sure if it is really useful)

"transaction": if true, the server first look if all procedures have a
rollback method, on any error in the batch, all processed method run
their rollback method

"context": JSON object accessible by all the methods (like a shared
parameter). If "sequential" is true, any update done to this context
by a method is seen by the next processed methods, otherwise, this
context is readonly (to prevent conflicts if non sequential methods
are processed in parallel)


Of course, some new error codes would be required for example with
"Missing Rollback"


Matt (MPCM)

unread,
Sep 4, 2009, 9:31:24 AM9/4/09
to JSON-RPC
I am very interested in the more advanced batch options, just not
within base specification. There is a huge body of work to be
leveraged and experimented with, hopefully we can do it with custom
implemented methods and work towards an adopted best practices with
the community. I think this fits well with the ever growing meta-
programming theme and cloud computing resources.

Keeping json-rpc itself simple allows us to create complex api's on
top. :)

A separate thread for those experiments might not be a bad idea.

--
Matt (MPCM)

Alexandre Morgaut

unread,
Sep 4, 2009, 9:40:34 AM9/4/09
to JSON-RPC
I agree ;-)

Roland Koebler

unread,
Sep 7, 2009, 3:00:12 PM9/7/09
to json...@googlegroups.com
Hi,

sorry for my late answer -- I've been on vacation the last weeks.

On Tue, Jul 21, 2009 at 10:09:54AM -0700, Matt (MPCM) wrote:
> @Roland:
> Is this something that we can agree to implement now without an
> implied return order?

I still prefer "return-in-order", since then simple clients don't need to
match the ids, and since I don't know *any* advantage of returning-not-in-order.

The server has to wait for all calls to complete anyway, before sending
the batched-response back. The only possible "advantage" of "not-in-order"
I read here (hope I haven't missed anything -- please tell me if I have) was
that it could be better with some kind of "streaming communication" -- but
there neither are any streaming JSON-encoders/decoders, nor do the usually
used protocols (e.g. HTTP) support such streaming messages.


Additionally, e.g. the OpenSocial-RPC looks quite similar to JSON-RPC 2.0
(except that they omit the "jsonrpc"-field), and also requires in-order.
(http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rpc-protocol)


There's one additional (minor) "thing" about in-order vs. not-in-order, I
noticed as I read my batched-example again:

Batched Call:

--> [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},


{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"} ]

<-- [ {"jsonrpc": "2.0", "result": 7, "id": "1"},
{"jsonrpc": "2.0", "result": 19, "id": "2"},
{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found."}, id: "5"},
{"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"} ]

When returning in-order, it's clear that the "Invalid Request."-error
belongs to the '{"foo": "boo"}'-call. When returning "not-in-order" you
couldn't tell...


@Matt:


> Should it turn out to make more sense with an implied order we can
> consider adding that restriction in for a later spec revision?

No, it wouldn't make much sense to add/remove such a restriction in a
later revision, since then you would have an additional incompatible
revision...


> That way 2.0 clients that use id's to handle responses would work with
> any later revision that might also require that order be preserved.
> Doing it in the reverse order would cause that not be true.

But newer clients won't work with older servers.
To be able to communicate with older servers and older clients, this would
probably result in servers returning in-order and clients expecting no
order... No, I think that wouldn't work -- we should now define if the
batched response should be in-order or not-in-order and then stick to
this. Everything else would cause confusion and incompatibilities.


regards,
Roland


Matt (MPCM)

unread,
Sep 7, 2009, 5:41:55 PM9/7/09
to JSON-RPC
> sorry for my late answer -- I've been on vacation the last weeks.

Welcome back : )

> I still prefer "return-in-order", since then simple clients don't need to
> match the ids, and since I don't know *any* advantage of returning-not-in-order.

It would simplify the assembly of a response array on the server
(though this is a minor issue).

> The server has to wait for all calls to complete anyway, before sending
> the batched-response back. The only possible "advantage" of "not-in-order"
> I read here (hope I haven't missed anything -- please tell me if I have) was
> that it could be better with some kind of "streaming communication" -- but
> there neither are any streaming JSON-encoders/decoders, nor do the usually
> used protocols (e.g. HTTP) support such streaming messages.

I was thinking primarily over sockets, but you are correct that these
types of technologies are not being used much today (AFAIK). Though, I
still think these are more likely to be appearing in the future. But
that is a big IMO and sits next to a huge grain of salt...

> Additionally, e.g. the OpenSocial-RPC looks quite similar to JSON-RPC 2.0
> (except that they omit the "jsonrpc"-field), and also requires in-order.
> (http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rp...)

This may be a very good reason for in-order, but I would still say the
gains are minimal. Below I explain why...

> There's one additional (minor) "thing" about in-order vs. not-in-order, I
> noticed as I read my batched-example again:
>
> Batched Call:
>
>     --> [ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
>           {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
>           {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
>           {"foo": "boo"},
>           {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
>           {"jsonrpc": "2.0", "method": "get_data", "id": "9"} ]
>
>     <-- [ {"jsonrpc": "2.0", "result": 7, "id": "1"},
>           {"jsonrpc": "2.0", "result": 19, "id": "2"},
>           {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request."}, "id": null},
>           {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found."}, id: "5"},
>           {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"} ]
>
> When returning in-order, it's clear that the "Invalid Request."-error
> belongs to the '{"foo": "boo"}'-call. When returning "not-in-order" you
> couldn't tell...

It can be inferred that any requests that are lacking corresponding
responses and are not notifications, are simply not valid jsonrpc
request objects. At least as far as the server is concerned...

In terms of who would hit this condition, we are talking about client
libraries that *must not* be making much effort to check that the
array of request objects is in fact filled with request objects. Since
the client needs to keep the requests to do the return pairing for an
ordered response, it seems trivial to me that the absence is just as
easy to handle as a specified "invalid request".

I still do not really see the gain in requiring order, except to match
the opensocial-rpc. It also amounts to wasted bandwidth for the gain
of telling the client something it can infer and should have
prevented. (i.e. For a 100 item batch, with 2 normal requests and 2
notification requests, we are sending back 96 errors (that the client
should have known about) and 2 valid responses.)

Could {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid
Request."}, "id": null} triggered by anything other than something the
client should have known?

Could the lack of it suggest anything other than unsent error object?

--
Matt (MPCM)

Alexandre Morgaut

unread,
Sep 7, 2009, 7:33:40 PM9/7/09
to JSON-RPC
Hi Roland

> The server has to wait for all calls to complete anyway, before sending
> the batched-response back. The only possible "advantage" of "not-in-order"
> I read here (hope I haven't missed anything -- please tell me if I have) was
> that it could be better with some kind of "streaming communication" -- but
> there neither are any streaming JSON-encoders/decoders, nor do the usually
> used protocols (e.g. HTTP) support such streaming messages.
>

I don't agree with that.
As SAX Parser could launch each interpreted xml-rpc call in parallel
processes, similar JSON parser could do it with JSON-RPC.
Once the request is fully read, the server can start the response
(Status line, headers) specifying a chunked transfert encoding and
write the result of each method once their process ends in separated
chunks.
The constraint is that the HTTP Server can't send a specific status
code depending of the result of the different tasks, it should send
then a simple 200 (ok) to say that the batch is globally accepted or a
400 (bad request) if the JSON isn't well-formed or isn't a valid JSON-
RPC batch (well, only if no process has been launched)

I don't think we'll have to wait 2 years before having that (if not
already implemented)

Browsers, with xhr, are not very good client for chunked JSON but they
can handle it with a setTimeout when readyState is 3 (headers
received, but body incomplete).
Other HTTP clients may handle it in a more efficient way

regards
Alexandre

Roland Koebler

unread,
Sep 11, 2009, 7:37:03 AM9/11/09
to json...@googlegroups.com
Hi,

[in-order vs. not-in-order response in batched calls]


> > Additionally, e.g. the OpenSocial-RPC looks quite similar to JSON-RPC 2.0
> > (except that they omit the "jsonrpc"-field), and also requires in-order.
> > (http://www.opensocial.org/Technical-Resources/opensocial-spec-v081/rp...)
>
> This may be a very good reason for in-order, but I would still say the
> gains are minimal. Below I explain why...

> [...]


> I still do not really see the gain in requiring order, except to match
> the opensocial-rpc.

Ok, if everybody else here is in favour of "not-in-order" responses (as it
seems to me), then I'll update the current proposal accordingly.

If anybody (except me ;)) is against "not-in-order" and for "in-order",
please tell me *now* and tell me *why*. Otherwise the spec will not
require any order in the batch-response.


[error-responses]


> It also amounts to wasted bandwidth for the gain
> of telling the client something it can infer and should have
> prevented. (i.e. For a 100 item batch, with 2 normal requests and 2
> notification requests, we are sending back 96 errors (that the client
> should have known about) and 2 valid responses.)

Right. This "wasted bandwidth" on error always exists, and does not
depend on the "in-order or not-in-order"-definition. But I wouldn't
see it as "wasted bandwidth" -- it does carry information, and tells
the client what went wrong.

If I understand you correctly, you think about omitting such
error-responses which would have '"id": null' in batch-responses, right?
I wouldn't do that, because (a) the returned erros contain information,
and (b) such errors should rarely occur (except the client-library is
extremely buggy), so that you don't win anything by omitting these.

> Could {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid
> Request."}, "id": null} triggered by anything other than something the
> client should have known?

It should only be triggered by an invalid request, which may be caused
by:
- the client sending an invalid request
- some errors on the "connection"
(e.g. corrupted data/lost packets etc. if this isn't prevented
elsewhere)
- a bug in the server


regards,
Roland

Matt (MPCM)

unread,
Sep 11, 2009, 3:39:51 PM9/11/09
to JSON-RPC
> [error-responses]> It also amounts to wasted bandwidth for the gain
> > of telling the client something it can infer and should have
> > prevented.  (i.e. For a 100 item batch, with 2 normal requests and 2
> > notification requests, we are sending back 96 errors (that the client
> > should have known about) and 2 valid responses.)
>
> Right. This "wasted bandwidth" on error always exists, and does not
> depend on the "in-order or not-in-order"-definition. But I wouldn't
> see it as "wasted bandwidth" -- it does carry information, and tells
> the client what went wrong.
>
> If I understand you correctly, you think about omitting such
> error-responses which would have '"id": null' in batch-responses, right?
> I wouldn't do that, because (a) the returned erros contain information,
> and (b) such errors should rarely occur (except the client-library is
> extremely buggy), so that you don't win anything by omitting these.

Outside of the batch concept, returning "id":null responses makes
sense, because you have the one-to-one mapping.

But inside batch, I was thinking it made sense to omit them. If I
understand this correctly, there is only one response error code that
could be returned inside of batch, no matter what the cause... -32600.
A batch call with 2 failures, would return two -32600 objects. But you
couldn't link them in any particular order (same error object shape,
so what does it matter anyway). So... unless you only have one
unaccounted for request object from your batch, then there is little
point in sending more than one from the server. From there I jumped to
not sending any... as the absence would clearly imply the same meaning
(with an understanding of the batch portion of the spec).

It is an edge case optimization of error objects, but it seemed
logical enough to me at the time. Not something I am worried about
however, just explaining how I got there. It also does not make sense
to omit the errors if there are more error objects than -32600 that
could be returned inside the batch output.

--
Matt (MPCM)

RedHog

unread,
Sep 16, 2009, 10:41:41 AM9/16/09
to JSON-RPC
I and a few friends have implemented JSON-RPC over TCP (or ssl) for
Python, in such a way that it is symmetric (both sides can call the
other side), and "streaming". We read the original (1.0) spec to mean
that sending multiple JSON objects, without any padding/separation,
was legal, and how tcp-json-rpc was supposed to work (the examples
suggest a newline/space separation might be required, and so we do
provide that, but don't require it in the parser).

Our code is available at http://github.com/niligulmohar/python-symmetric-jsonrpc

If this reading is correct, there is no need for batch at all, unless
2.0 deviates from the 1.0 semantics entirely.

What's your take on this? Is that how you read the 1.0 spec.?

I have also posted a message on the google group about how to
implement this symmetry properly in JSON-RPC-over-HTTP...

Matt (MPCM)

unread,
Sep 16, 2009, 11:30:26 AM9/16/09
to JSON-RPC
1.0 did allow bi-directional request/response sending.

2.0 has a defined client/server roles, where bi-directional operations
are obtained by having each side operate as both a client and server,
possibly over the same channel (not defined). In the web browser world
it is normally the browser that is acting as the client. If you use
some type of comet with the browser, this could allow the browser to
act like a server more easily, as well as serving that bi-direction
aspect.

Batch could have existed as it does in 2.0, in 1.0. But you are
correct that there would have been little reason.

--
Matt (MPCM)

Joe Engel

unread,
Oct 6, 2009, 2:36:35 AM10/6/09
to JSON-RPC
JSON-RPC 2.0 specifies that batch requests can be sent as a simple
array, which means

- we can't identify the request as jsonrpc until we look inside the
array and inspect the items.
- if there is a problem processing the batch as a whole, we don't have
a request id to return alongside the error.
- we can't make any indication of how the batch should be processed
(In series or parallel? If in series, do we stop for errors? Rollback
a transaction?)

If, as Omi suggested, we pass the method list as an array to a batch
function

- we can identify the batch as jsonrpc in the same fashion as for
single requests. (Because it is a single request.)
- we can return an id with all but parse errors.
- we can add additional params as required to describe how the batch
is to be handled.

Then under 'Batch / Multicall' in the spec, we can simply say:

"Implementations may batch requests by defining a method that accepts
an array of rpc calls, and returns an array of rpc responses."



-----------------------------------------------------

Alexandre Morgaut

unread,
Oct 6, 2009, 7:46:21 AM10/6/09
to JSON-RPC
> - we can't identify the request as jsonrpc until we look inside the
array and inspect the items.
> - if there is a problem processing the batch as a whole, we don't have
a request id to return alongside the error.

I clearly agree with this problem
There is to ways to handle it:


1 - Make a specific remote procedure named with the prefix reserved
for extensions

{
"jsonrpc": "2.0",
"method": "rpc-batch",
"params": [
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id":
"1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract", "params": [42,23],
"id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get", "params": {"name":
"myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
],
"id":"batch-12"
}


2 - Update the specification to embed the batch in a JSON object

{
"jsonrpc": "2.0",
"batch": [
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id":
"1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract", "params": [42,23],
"id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get", "params": {"name":
"myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
],
"id":"batch-12"
}

(but this wouldn't be compatible with existing implementations)


> - we can't make any indication of how the batch should be processed
(In series or parallel? If in series, do we stop for errors? Rollback
a transaction?)

This is actually up to the server to decide how it will handle the
request (series or parallel)
The server will make its best to send responses more most of the
requests hoping none of the potential Internal error are Fatal...
We actually agreed that more specific requirements like ordering
requests, automatic rollbacks, or shared context... remained to other
specifications
A remote procedure could also be written to handle such options,
taking procedure names and arguments as its own parameters with
additional ones
If we extend the previous example :

{
"jsonrpc": "2.0",
"method": "rpc-batch",
"params": {
"ordered": true,
"context": {"client-sys": "Mac OS X"},
"batch":[
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id":
"1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract", "params": [42,23],
"id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get", "params": {"name":
"myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
]
},
"id":"batch-12"
}

Matt (MPCM)

unread,
Oct 6, 2009, 10:09:39 AM10/6/09
to JSON-RPC
Any user right now can implement their own batch processing method and
expose it. This works nicely if you have wrapper functions of the same
kind, like a sum function and a sums function that loops and calls
sum. It's all behind the json-rpc server line, and in the api itself.
But often the meaning is not that straight forward and you want to
execute a bunch of unrelated functions, either by name or content.
This came up for a while in the yahoo group during the 1.1/1.1ALT/1.2
days as `multicall`.

The problem I experienced with doing json-rpc batch inside an exposed
method was primarily an issue of cleanness, logging, and evaluation
layering. For the most part batch in that form requires specially
aware logging (and/or aware log analyzers), protection against deeply
nested batch requests, and while easy to implement solves what is
really a different problem in my mind. The order specific, on error
fail transaction magic is what belongs inside the method, and that is
quite a long from being ironed out at all, and probably will always
live outside the core spec. But that type of problem belongs in the
api as a method, this concept of batch does not.

Batch in 2.0, as I have understood it, is best implemented as the end
part of the transport handling layer prior to the json-rpc marshaling
itself. Just like any other environment it has to parse out what it is
passed for input, figure out if it is json, then if it is a json-rpc
request, and then pass it along into the json-rpc marshalling section.
This makes it function much more like an immediate proxy, but could be
used to split the work to many already spinning json-rpc servers
behind the scenes.

Changing the batch container from an array to an object so we can add
descriptive headers also seems to miss the point in my mind. Batch is
not a json-rpc request... that solves a different and possibly more
complex problem, this is just an array of requests to be processed.
Implementation support is as easy as an if_array_check and loop ahead
of the invocation code, but leaves lots of room for more fancy
parallel/non-sequential magic.

Our request objects are getting cluttered enough, lets keep batch
simple and clean. :)

--
Matt (MPCM)

Antony Sequeira

unread,
Oct 6, 2009, 3:37:25 PM10/6/09
to json...@googlegroups.com
I only lurk on this, but something about this thread is making me respond :)

This is not at any specific message in this thread.

I do not have any specific issue or suggestion - but the basic thing
to note is -
you are sending data and a half baked set of instructions in json-rpc
- half baked in the sense json-rpc is not turning complete (and i am
not suggesting that it necessarily be TC)
One way to solve all your problems is to send full on javascript and
execute javascript (even today this should be possible out of the box
in .net and java at least and of course the browsers) and then deal
with security :)
As long as you are not using a Turing complete mechanism you will have
issues and that is ok, you just have to make tradeoffs. You need to
keep that in mind especially in the design discussions I am seeing in
this thread.

I don't think I am completely off the mark here - for example the question above

> - we can't make any indication of how the batch should be processed
(In series or parallel? If in series, do we stop for errors? Rollback
a transaction?)

is simply answered by - hey, whatever the block of javascript code the
client sent me is what I am going to do says the server.

I see lot of things like templating mechanisms, configuration
mechanisms etc that start out as 'simple' and then become a mess
trying to get out of the hole of not being TC
(like - oh we now need a conditional config, lets now add an 'if' )
and rpc mechanisms are probably in the same category

Just my 2C, back to lurking

-Antony

Matt (MPCM)

unread,
Oct 6, 2009, 4:08:23 PM10/6/09
to JSON-RPC
@Antony Sequeira

To a large extent though, that half-baked concept is RPC. In my early
`Ajax` days using JSRS, the prototype I wrote passed an xml format up
to the server and shipped fully generated javascript src back down to
the browser. It didn't scale, or look pretty, but it proved the point
that interactive web apps worked. They just needed to be less hackish
before most enterprises would use them.

In our more fluffy, cloudy, Internet ;) ... shipping the code to run
the job, along with the job data is definitely not out of place. I am
all for JavaScript all the way down (and up)... it makes life lovely.
But I don't see the major vendors just simply allowing execution of
client code within traditional applications. Its a scratch for a
different itch, and will have its place in all of our coding futures,
but definitely an interesting concept if your application workload
functions like that. Sort of like procedurally generated content, and
oddly enough NURBS from 3D modeling. There is something about the
simplicity of the concept and the presentation.

Most json-rpc clients are not acting like or on behalf of smart-
agents. Which is where I really see the data+code payload working the
best. I don't think batch complicates json-rpc 2.0 much at all, in
fact I'm not sure what would be added after 2.0 that could not stay in
extensions. Which is why I shudder a little that there is a "2.0" in
the object. Versions are dangerous. Batch could stay in an extension,
but the details in the spec offer a simple solution to an often asked
feature. Anything more than that and you need to roll your own, which
is how json-rpc started out after all...

By all means start a new thread of the subject, just don't steal my
batch thread and unlurk anytime to help me/us keep json-rpc simple. :)

--
Matt (MPCM)

Lorenzo Pastrana

unread,
Oct 8, 2009, 4:15:13 AM10/8/09
to json...@googlegroups.com
Hi,
I've been very concerned lately on this kind of issues (being forced to work in PHP, wich I read when you speak about templating mechanisms), could you elaborate on what you believe would prevent JSON RPC 2.0 to be Turing complete ?

Thx.

Lo.

Jay

unread,
Oct 8, 2009, 4:32:17 AM10/8/09
to json...@googlegroups.com
Please keep in mind that JSON-RPC is a protocol. Turing completeness
is not something that should be desired here. HTTP and TCP are
additional examples of protocols which are also not "turing complete."

My view, and please someone correct me if I'm way off base here, is
that JSON-RPC is a protocol for communicating with an API, which can
and should be written in a Turing complete language. The goal is not,
and should not ever be, to allow clients to execute arbitrary
instructions on a backend server. That would be Very Bad, not to
mention a Gigantic Security Hole, which is why Turing completeness is
not and should not be a goal for this or any other protocol that
involves untrusted sources.

Jay

Lorenzo Pastrana

unread,
Oct 8, 2009, 4:47:40 AM10/8/09
to json...@googlegroups.com

Right ...

And I believe that to a certain extent, JSON RPC 2.0 _is_ Turing complete in the sense that it can 'vehicle' any kind of instruction set, in a very flexible way.

This is why I'm particularly curious about what can make someone feel the contrary ...

Lo.

Alexandre Morgaut

unread,
Oct 8, 2009, 4:54:37 AM10/8/09
to JSON-RPC
> The goal is not,
> and should not ever be, to allow clients to execute arbitrary
> instructions on a backend server. That would be Very Bad, not to
> mention a Gigantic Security Hole, which is why Turing completeness is
> not and should not be a goal for this or any other protocol that
> involves untrusted sources.

I don't totally agree on this point
SSH is a protocol which allow to execute arbitrary instructions on
backend server, and it is widely used
HTTP has DELETE, PUT, and POST method which are not intended to only
transport information but also to compute it
The point is, as you said, to Trust the client, that's the goal of
authentication and ssl encryption & certificates which are neither
defined in JSON-RPC nor in XML-RPC, HTTP...
(HTTP basic and digest Authentications are an external specification)

So a protocol like JSON-RPC could be used "to execute arbitrary
instructions" as long as the client is authenticated, Authorised, and
using a secured communication channel (like with HTTPS)

Jay

unread,
Oct 8, 2009, 5:09:12 AM10/8/09
to JSON-RPC
To my knowledge, it's not possible to ever fully trust a web client.

-Any web client is by definition running on a user's computer, not on
the server.
-Any code running on a user's computer, the user can get access to,
and decompile.
-Any keys/certificates/etc contains within that code can be extracted
given enough time and effort.

Imagine creating a piece of client software that establishes an SSH
connection to your server for the user with stored keys and
credentials, in order to execute certain commands on the server. The
act of imagining such a thing should cause your head to explode,
because including the keys & credentials in the client means anyone
can get them out, and "pretend" to be the client by decompiling it or
reverse engineering it based on the network activity.

Jay

Lorenzo Pastrana

unread,
Oct 8, 2009, 5:51:14 AM10/8/09
to json...@googlegroups.com

SSH & HTTP _are_ pure 'transport' protocols :

What executes the (possibly arbitrary) instructions is the program that handles the incoming pipe : a shell session or a specified program in the case of ssh or the recipient script in the case of an HTTP request.

SSH has a tty syntax to form requests/response that is translated to programs in the stdin/stdout way, HTTP(S) has none (or tons of) idioms, including JSON RPC 2.0 ...

I certainly can think of a (completely pointless) assembly instructions set to be remotely executed via JSON RPC 2.0 that would be Turing complete ...

Lo.

Alexandre Morgaut

unread,
Oct 8, 2009, 6:14:20 AM10/8/09
to JSON-RPC
The point is that https isn't less secure than ssh
After if you want to argue on WAN security, that's another point (hard
to hear for online banks ;-) )
both can be used either on LAN or WAN, can be restricted through a
VPN, or could use any other security techniques

Lorenzo Pastrana

unread,
Oct 8, 2009, 10:08:40 AM10/8/09
to json...@googlegroups.com
No sure how this relates to Turing completeness .. ;P
Lo.

RedHog

unread,
Oct 13, 2009, 5:15:28 AM10/13/09
to JSON-RPC
> Outside of the batch concept, returning "id":null responses makes
> sense, because you have the one-to-one mapping.

That depends on the transport. You might be correct for HTTP w/o keep-
alive, but for anything else, there is just no guarantee. For example
over pure TCP, there isn't any other mapping between request and
response than the ID - responses can come interleaved and delayed and
in any order.

Actually, it makes more sense with a null "id" _inside_ a batch,
because there you at least have some kind of grouping (and, if you
want too, ordering).
Reply all
Reply to author
Forward
0 new messages