Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Be less dependent on axios #4

Open
simplesmiler opened this issue Jul 21, 2020 · 4 comments
Open

Be less dependent on axios #4

simplesmiler opened this issue Jul 21, 2020 · 4 comments
Labels
enhancement New feature or request
Milestone

Comments

@simplesmiler
Copy link
Owner

simplesmiler commented Jul 21, 2020

Motivation:

  1. Axios does not support response streaming in browser, only in Node (there is intent, but no visible progress so far.). A readable "stream" can be acquired from Blob response, but the whole response body is buffered in memory anyways. Fetch, on the other had, supports streaming, although not in every browser.
  2. Typed request builder can also be useful to developers who do not use Axios.

TL;DR

Current problems are:

  1. We can not be independent of axios, because we need AxiosResponse generic.
  2. Axios can not be peer dependency because TypeScript does not work well with peer dependencies. Not a problem anymore, was solved by also having it as dev dependency.

Details

To be independent of axios, we have to be able to arbitrarily wrap response types (e.g. Pet into AxiosResponse<Pet>).

But TypeScript does not support:

  1. First class generics, e.g. generic as parameter for another generic.
    type Wrap<T> = { data: T };
    const taxios = new Taxios<Api, Wrap>(agent); // error: Wrap is not a type
  2. ReturnType of generic function.
    type Wrap<T> = { data: T };
    type Wrapper = <T>() => Wrap<T>;
    type WrappedNumber = ReturnType<Wrapper<number>>; // error: Wrapper is not a generic

So far I could not find a way around that.

@simplesmiler simplesmiler added the enhancement New feature or request label Jul 22, 2020
@simplesmiler
Copy link
Owner Author

Maybe this still possible with classes, because classes can have generic methods and can themselves be generic parameters.

But maybe we don't want per-agent response type at all, but always want native Response type branded with T?

@crutch12
Copy link
Collaborator

But maybe we don't want per-agent response type at all, but always want native Response type branded with T?

Native Response is too uncomfortable to work with. I think this is the reason why people use axios.

If you want to reject axios, I think we should create another npm module for that

@simplesmiler simplesmiler added this to the 0.3.0 milestone Dec 24, 2021
@simplesmiler
Copy link
Owner Author

TLDR: I think axios is slowly becoming a "jQuery".

I think people use axios mostly because:

  • XMLHttpRequest is awful to work with. Fetch feels much better in comparison (but not perfect), and axios feels even better (but at a cost of not supporting web streaming).
  • Axios has interceptors for "global" behaviors, like logging, authentication and retry.

Native Response is too uncomfortable to work with.

I would like to argue that it's not really. Response and AxiosResponse have mostly the same interface, with only notable exceptions being:

  • AxiosResponse has config: AxiosConfig, which is mostly used in interceptors.
  • Response is returned before all data has arrived, so it has to be { json(): Promise<T> } instead of { data: T }. But I personally don't see much difference between taxios.get('/users').then(r => r.data) and taxios.get('/users').then(r => r.json()).

@simplesmiler
Copy link
Owner Author

Judging by axios/axios#4209, there is intent in axios to support web streams.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants