perry-mitchell / cowl

Request cowl for making requests from NodeJS/Browser/React-Native
MIT License
3 stars 1 forks source link

Add a "migrating from fetch" guide #5

Open mikesol opened 4 years ago

mikesol commented 4 years ago

I'm looking at cowl in relation to https://github.com/buttercup/buttercup-core/issues/229, and it is tough to know the best way to migrate from fetch. It's also tough to know what the advantages are of cowl over fetch from the readme.

Here are the possible options for fetch.

    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': 'application/json'
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow', // manual, *follow, error
    referrer: 'no-referrer', // no-referrer, *client
    body: JSON.stringify(data) // body data type must match "Content-Type" header

As I understand it, mode, cache, credentials, redirect, and referrer do not have analogs in cowl. Is this correct?

For responses, the API seems pretty straightforward, with the only difference that cowl stores the body in a buffer and that it does not automatically parse the body given the response type.

Also, fetch has some logic under the hood to do things like guess the Content-Type and Content-Length - are these present in cowl?

In general, what would be the main advantages of using cowl over fetch? Because fetch is battle-tested, has very few bugs, and will be known by most new contributors to a JS project, one would need IMO a pretty compelling reason to migrate to something new. Not saying that cowl lacks this, but rather that it is not apparent what the advantages are when reading the README.

perry-mitchell commented 4 years ago

Hi @mikesol -

As I understand it, mode, cache, credentials, redirect, and referrer do not have analogs in cowl. Is this correct?

Yes, some of those haven't yet been implemented, or may never be. I can see redirect being useful, but I'm not sure of the others. Because cowl is using XHR for now under the hood (will migrate to node's http/https later, potentially, to support streams), some of these options may not be possible to implement yet.

cowl stores the body in a buffer and that it does not automatically parse the body given the response type

Actually cowl does auto-parse results - see here. It reads the content-type response header to derive the type. This isn't as foolproof as it could be.

Also, fetch has some logic under the hood to do things like guess the Content-Type and Content-Length - are these present in cowl?

Content-Type could be set automatically, for sure. Content-Length I don't like because it's illegal to set in the browser. The goal of cowl is first and foremost cross-platform compat, so its reduced API needs to work everywhere in the same manner (Node+Browser+ReactNative).

fetch is battle-tested, has very few bugs, and will be known by most new contributors to a JS project

Fetch is implemented very poorly across all platforms in my opinion.. Only the browser really stands up, Node has good alternatives but RN has some very poor (or had, at the time I had the experience) implementations. It left me with axios, which is now defunct basically. cowl is an attempt to take the basics to every platform in the same manner. Using multiple fetch libraries is not an option as buttercup-core is isomorphic.

Cowl will always be far from the perfect generic request library, and I don't think it should ever try to be the full toolkit axios/fetch are. It should have the basics so that it can support platforms like buttercup without the need for us to do per-device monkey patching.

perry-mitchell commented 4 years ago

To your point, I definitely agree the docs could be updated to include a brief comparison and migration guide.. but perhaps the purpose needs clarification first, so that users won't expect something cowl can't provide.

mikesol commented 4 years ago

A few more questions, just to understand the use case better.

Another way to frame the question: if someone implemented a cross-platform compat version of fetch that was coded/maintained in a more modern way, would there be a compelling reason to use cowl?

I ask all this with an outsider's perspective in hopes that it is valuable! These are the types of questions I try to (and sometimes fail to) ask myself before putting a lot of effort into a new project.

perry-mitchell commented 4 years ago

What, in your opinion, is implemented poorly with npmjs.com/package/isomorphic-fetch

In its case, it's not a matter of being implemented poorly per se, but it does use a non-isomorphic package setup. Buttercup builds 2 outputs: node and web. These are used in react-native (besides desktop and browser), which is a complex environment. It's simply too much trouble to morph dependencies and then dependencies-of-dependencies into the correct form for each environment. We have long dependency chains in some areas and we want to stay well away from options that present more than one target.

Instead of a new package with new syntax, would it be more helpful to build a better version of isomorphic fetch?

I get that, I do.. and this will sound like I'm a bit bitter but there's enough fetch and fetch-polyfill and isomorphic-fetch libraries going around that I'm happy to stay well away from them. If I were to go with a fetch-style API and want to add non-standard methods - it then gets a bit messy.

I also have my own opinions on a request framework, and I perhaps don't subscribe to it needing to be a standard.. to each their own. I don't like that the url parameter is a mandatory string with fetch, for one, and prefer to use a configuration object in almost all cases (bar simple GETs).

perry-mitchell commented 4 years ago

I completely get if it's not of interest to invest an amount of time into another person's interpretation of a rather common toolset.

Cowl has a very specific use case - which is to be broadly usable in the environments it was designed for. The API will have to sacrifice a bit to ensure that it works that way, and I for sure haven't worked out all the nuances of each platform in a way that ensures stability for every feature. Still very much a WIP 😄

mikesol commented 4 years ago

It sounds like a really cool idea and project! It just makes the collab on buttercup more challenging for me personally, as it requires learning a new library. But I'm sure there are other parts of buttercup I could dive into with a less steep learning curve, I will check out the issues list again this week.