Re: Response data should always be in a top-level "value" property.

Bottom posted

On Mon, Oct 3, 2016 at 10:01 PM, James Graham <james@hoppipolla.co.uk>
wrote:

> On 03/10/16 21:00, Jason Juang wrote:
>
>> I don't disagree with this proposal.
>>
>> Worth noting that this was previously litigated at TPAC 2014
>> <https://www.w3.org/2014/10/30-testing-minutes.html#item05>, where there
>> were two related resolutions:
>>
>>> resolution: remove response body and just send back dictionary
>>> resolution: use 'value' key for primitives
>>>
>>
>> I think the order of events was:
>> - the response used to have a "status" field and a "value" field
>> - the "status" field was removed in favor of using HTTP status codes
>> - the "value" field was removed for non-primitive responses because it
>> seemed redundant to wrap the response in '{"value": ... }'
>>
>> I can't quite recall whether there were other arguments for "unwrapping"
>> the response, other than that it seemed unnecessary at the time.
>>
>> I think the consistency argument (#2) alone is more compelling than
>> that. Point #3 is also kind of nice; it allows for future protocol
>> modifications to add additional fields, should that become necessary.
>>
>
> I don't really think the consistency argument has that much value. In
> either case you need to know which type to coerce to, which you can only
> know if you know the command. Blindly coercing to a type on the remote end
> would be a spec violation (because unknown fields must be ignored), and I
> would expect clients to behave the same way. Needlessly wrapping just
> produces another layer of indirection.


In Selenium there's a pipeline for decoding a response. The first step
involves taking the raw json encoded as a string and decoding that to a
JSON object of some kind. Response values are then pulled out of the json
and pushed into a selenium's own "Response" object, with the value having
been coerced to an exception if necessary, or left as a raw map, list, or
primitive type. The next stage of the pipeline populate the object returned
to the user of the local end.

There is a need to wrap primitive types, as Andreas has pointed out that
some JSON parsers get grumpy if presented with something that isn't an
object to decode.


> I also don't care for the extensibility argument; spec extensions can
> avoid collisons simply by picking a new name and intermediaries or vendor
> extensions should vendor-prefix any field names using a reserved character
> (there is an issue about using colon for this purpose so that you get
> vendor:foo properties).
>

This is the same problem that we faced with "element": we don't know which
fields are safe and which are not. Putting the value being returned into a
"value" property means that it's possible to safely decorate responses
without worrying about clashing namespaces. Without doing this, it's not
possible to guarantee no clashing with values being returned to the user.


> In any case this seems like a rather large change to propose after
> agreeing a short timetable to reach PR. I don't intend to block the
> proposal if it's something that everyone agrees is right, but I would
> encourage anyone else wanting to propose fundamental changes to things that
> have been explicitly agreed and in the spec for several years to do so
> sooner rather than later otherwise I fear Mike is going to have a hard time
> making a credible case that we will ever actually finish anything.
>

Fortunately, most commands already return their value in a top-level
"value" property. Those that don't are mostly to do with window sizing and
positioning. In the geckodriver, there are places in the spec that claim
the return value should be serialised, but where nonetheless the actual
implementation puts the data into a "value" property anyway ("Get Active
Element" would be one of those places). So it seems that this also makes
the spec more conformant to actual existing implementations.

Simon

Received on Tuesday, 4 October 2016 09:48:49 UTC