[whatwg] Fetch: use separate methods instead of one `to` method in FetchBodyStream

Reading the Fetch spec, the only major issue I have with the API is the
`to()` method on the FetchBodyStream. Having different kinds of behavior
behind one function that takes a string that determines the actual
underlying implementation is bad enough as it is (think about canvas's
`getContext()` for example), but to make matters worse this one's async so
you can't even wrap it in a try-catch to see if the transform is
implemented or not, but you have to wait for the promise to reject.

I find this quite a bit future hostile. If you wanted to feature detect if
for example JSON transform is implemented, you'd do something like this:

var doesFetchSupportJson = function () {
    return fetch("data:application/json;base64,e30=").then(function
(response) {
        return response.body.to("json");
    }).then(function () {
        return true;
    }).catch(function () {
        return false;
    });
};

Whereas if you had it as a separate method, e.g. asJSON (to avoid conflict
with toJSON), the detect would be synchronous and as simple as follows:

var doesFetchSupportJson = function () {
    return "asJSON" in FetchBodyStream.prototype;
};

Another bad example of using strings for these kind of things, from much
closer, is XHR's responseType where it's excruciatingly painful to try to
detect for example whether responseType "json" (it may throw when you set
it, it may result in the `error` event or it may silently fail and set the
JSON as string to response) is supported, let alone "arraybuffer".

Feature detection is not the only concern though, another one is that it
encourages putting a lot of complexity behind one flag (just like
responseType) which is likely to lead to interoperability issues.
Separation of concerns and all that.

Therefore I'd like to suggest that we use separate methods for each
transform, i.e.:

asJSON()
asText() // or maybe asString, for parity with the toJSON, toValue,
toString family of methods.
asArrayBuffer()
asBlob()

Maybe even `readAsX` instead of `asX` for more actionable method names. I
don't have a strong preference over the method names, as long as they're
separate methods. :)

Cheers,
Jussi

Received on Monday, 16 June 2014 10:57:56 UTC