Wednesday, 9 August, 2017 UTC


Summary

Making HTTP requests is a core functionality for modern languages and one of the first things many developers learn when acclimating to new environments. When it comes to Node.js there are a fair amount of solutions to this problem both built into the language and by the community. Let’s take a look at some of the most popular ones.
We’ll be using NASA’s Astronomy Picture of the Day API as the JSON API that we are interacting with in all of these examples because space is the coolest thing ever.

Before moving on, make sure you have up to date versions of Node.js and npm installed on your machine.

HTTP – the Standard Library

First on our hit parade is the default HTTP module in the standard library. With this module, you can just plug and go without having to install external dependencies. The downside is that it isn’t very user friendly compared to other solutions.
The following code will send a GET request to NASA’s API and print out the URL for the astronomy picture of the day as well as an explanation:
const https = require('https');

https.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', (resp) => {
  let data = '';

  // A chunk of data has been recieved.
  resp.on('data', (chunk) => {
    data += chunk;
  });

  // The whole response has been received. Print out the result.
  resp.on('end', () => {
    console.log(JSON.parse(data).explanation);
  });

}).on("error", (err) => {
  console.log("Error: " + err.message);
});
Much of the HTTP, and the HTTPS, module’s functionality is fairly low-level. You’re required to receive response data in chunks rather than just providing a callback function to be executed as soon as all of the data is received. You also need to parse the response data manually. This is fairly trivial if it is JSON formatted, but it is still an extra step.
One other problem is that this module does not support HTTPS by default, so we need to require the https module instead if the API we are using communicates over HTTPS.
It may take a bit more effort to get the data you want, but is a great utility if you don’t want to add too many dependencies to your codebase or want access to its low level functionality.

Request

Request is a simplified HTTP client comparable to Python’s requests library. This library is much more user friendly than the default http module and has been considered a go-to for the community for several years.
This has been my personal choice since I’ve started using Node.js, and is great for quickly getting things done. Unlike the http module, you will have to install this one as a dependency from npm.
Run the following in your terminal from the directory you want your code to live in:
npm install [email protected]
You’ll see that you need much less code to accomplish the same task that we did above:
const request = require('request');

request('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', (err, res, body) => {
  if (err) { return console.log(err); }
  console.log(JSON.parse(body).url);
  console.log(JSON.parse(body).explanation);
});
Although it is much more high level than the standard library’s solution, you still need to parse your own response data. Request is a fantastic option if you just want an easy to use library that deals with HTTP requests in a sane way.

Axios

Axios is a Promise based HTTP client for the browser as well as node.js. Using Promises is a great advantage when dealing with code that requires a more complicated chain of events. Writing asynchronous code can get confusing, and Promises are one of several solutions to this problem. They are even useful in other languages such as Swift.
To install Axios from npm, enter the following command in your terminal:
npm install [email protected]
The following code will accomplish the same task of logging the URL to and of explaining the astronomy picture of the day:
const axios = require('axios');

axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
  .then(response => {
    console.log(response.data.url);
    console.log(response.data.explanation);
  })
  .catch(error => {
    console.log(error);
  });
Notice that you don’t have to parse the response yourself if the data is in JSON format. Pretty convenient! You can also see that error handling is done with .catch() since we are using promises now.
You can even make multiple concurrent requests with axios.all if you wanted to do something like get the astronomy picture of two different days at once:
var axios = require('axios');

axios.all([
  axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-03'),
  axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-02')
]).then(axios.spread((response1, response2) => {
  console.log(response1.data.url);
  console.log(response2.data.url);
})).catch(error => {
  console.log(error);
});
Asynchronous code can easily become over complicated and unpleasant to deal with, and the way Axios tackles this problem may make your life easier in the long run.

SuperAgent

Similarly to Axios, SuperAgent is another popular library primarily used for making AJAX requests in the browser but works in Node.js as well. Install SuperAgent with the following command:
npm install [email protected]
What is cool about SuperAgent is that you have other useful functions that you can chain onto requests such as query() to add parameters to the request. We’ve been just manually adding them in the URL in the previous examples, but notice how SuperAgent gives you a function to do this:
const superagent = require('superagent');

superagent.get('https://api.nasa.gov/planetary/apod')
.query({ api_key: 'DEMO_KEY', date: '2017-08-02' })
.end((err, res) => {
  if (err) { return console.log(err); }
  console.log(res.body.url);
  console.log(res.body.explanation);
});
Just like with Axios you don’t have to parse the JSON response yourself, which is pretty cool.

Got

Got is another choice if you want a more lightweight library. It is also available to use in Twilio Functions.
Again, install Got with npm:
npm install [email protected]
Similarly to Axios, Got works with Promises, but it does not parse the JSON response for you. The following code will work as the rest of the examples do:
const got = require('got');

got('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY').then(response => {
  console.log(JSON.parse(response.body).url);
  console.log(JSON.parse(response.body).explanation);
}).catch(error => {
  console.log(error.response.body);
});
Got is great if you want a smaller library that feels likes “bloated” than something like Request.

Final Thoughts

This doesn’t cover all of the solutions, but now you see how the basic functionality works in a few of the most popular HTTP libraries in Node. There are also libraries such as node-fetch which ports the browser’s fetch functionality to the backend.
Other languages have a similar variety of libraries to tackle this problem. Check out these other tutorials in Python and Ruby.
What are your favorite ways to send HTTP requests? Feel free to reach out and let me know or ask any questions:
  • Email: [email protected]
  • Twitter: @Sagnewshreds
  • Github: Sagnew
  • Twitch (streaming live code): Sagnewshreds
HTTP Requests in Node.js