Skip to content

Instantly share code, notes, and snippets.

@musghost
Last active January 24, 2018 16:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save musghost/fbdd3be0460988ea052b5d6ad25d46c9 to your computer and use it in GitHub Desktop.
Save musghost/fbdd3be0460988ea052b5d6ad25d46c9 to your computer and use it in GitHub Desktop.

Overview

Choosing an http client is one of the most common practices when developers try to consume APIs and this is most common when front-end developvers are builing frameworks using low level APIs. In the case of Angular, for example, it provides an http client out of the box so you don't have to worry about it. But imagine that you're building your own framework or you're building something light with lightweight libraries; then, choosing your tools become a complicated thing if you try to cover all corner cases in terms of performance. But, probably there are another topics that you have to keep in mind and you haven't event thought. This post shows how to chose an http client keeping in mind some important considerations. This would give you food for thought whenever you make a technical choices.

Popular JavaScript HTTP clients

The following is a list of the most popular http client libraries written in JavaScript. They were considered in the list because they have more than 2,000 stars in github; probably there should be a better way to measure the popularity of a package/library, but for now this research assumes that this is a good fact to consider.

got

got. The request parameters remains the same. To make this library work only the response of the request has to be changed. Example of usage:

const got = require('got');

(async () => {
  try {
    const response = await got('sindresorhus.com');
    console.log(response.body);
    //=> '<!doctype html> ...'
  } catch (error) {
    console.log(error.response.body);
    //=> 'Internal server error ...'
  }
})();

restler

restler. For this library the request mechanism has to be changed and the response as well. Example of usage:

var rest = require('./restler');

rest.get('http://google.com').on('complete', function(result) {
  if (result instanceof Error) {
    console.log('Error:', result.message);
    this.retry(5000); // try again after 5 sec
  } else {
    console.log(result);
  }
});

request

request. For request, if the client wants to configure the options of the request it has to send a plain object.

var request = require('request');
request('http://www.google.com', function (error, response, body) {
  console.log('error:', error); // Print the error if one occurred
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage.
});

reqwest

reqwest. Reqwest accepts the same parameters as request (the library mentioned above), but also can use the url as first parameter and the callback as second parameter. Example of usage:

reqwest('path/to/html', function (resp) {
  qwery('#content').html(resp)
})

reqwest({
    url: 'path/to/html'
  , method: 'post'
  , data: { foo: 'bar', baz: 100 }
  , success: function (resp) {
      qwery('#content').html(resp)
    }
})

superagent

superagent This offers an interface with different methods, depending on the verb is the name of the method. Example of usage:

request
  .post('/api/pet')
  .send({ name: 'Manny', species: 'cat' }) // sends a JSON post body
  .set('X-API-Key', 'foobar')
  .set('accept', 'json')
  .end((err, res) => {
    // Calling the end function will send the request
  });

fetch API is out of the box

Fetch provides a way to perform http requests with a lot of features and is supported by most of the modern browsers. It is widely used by the front-end community, specially React and React Native developers. Since it's out of the box this should be enough reason to choose it.

But, what happens if we're bulding an isomorphic framework. In this case, we shouldn't be worried of the Web API side but in the node side. Node offers another interface to perform http calls different than fetch, it offers the http and https interfaces. From this perspective, we can eather choose one of the isomorphic libraries listed above or just write an interface that acceps both, fetch from the Web side and http/https from the node side.

Also, think of this: imagine that a considerable amount of people the people that use your framework or library want to support old browsers. Then, this problem gets a little bit more complicated.

Let's analize fetch in terms of support.

Browser support of fetch in current browsers

Not all the browsers support it nowadays and that's something important to keep in mind when choosing interfaces for web development. To have a better picture of the current status of the support of fetch in the modern browsers we can take a look at the table in https://caniuse.com/#search=fetch

From the table, we can conclude that using fetch won't allow our applications to work in IE, Opera mini and UC Browser for Android, and according to the percentage of users using those browsers, IE with 3.32%, Opera Mini with 2.84% and UC Browser with 8.24%, we can reach about 85% of the total users goblally. We have to keep in mind that this is a vague estimation but gives a better undestanding of the context when making decisions.

Fetch in node

As mentione above node provides an API to perform http requests using both http and https modules but not an interface like fetch like in the browser. Fortunately, there's a package that offers a lightweight module with the same set of functionalities, making it compatible with the fetch interface of the browser.

Conclusion

If your library needs to use an isomorphic http client library to perform the same operations in the Web side and node side you can use something like axios or isomorphic-fetch, the problem comes when those libraries have several dependencies and that's not good specially for web browser applications.

Finally, we can include in the documentation a list of http clients that work similar to fetch:

We have three different aproaches to make something simple and powerful:

  • Depend on a single isomorphic library. This makes it easy and reliable but overloads the dependence tree.
  • Rely on an standard (the current apporach). This can be super flexible when using different libraries instead of attaching it to a single one. The problem is that two different libraries could be used, then one could offer some features that the others couldn't provide.
  • Develop these functionalities making it isomorphic using the standard modules. This dettaches your library of framework from any other library and makes it lightweight. The problem is that requires more develop and tests (extra resources).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment