How to Make API Calls in Node.js

Published: Tuesday, June 14, 2022

Greetings, friends! In the last tutorial, I discussed how to make API calls in the browser. In this tutorial, we will learn how to make API calls using the Node.js runtime. We can make API calls natively in Node.js using one of these two APIs:

  1. HTTP Module
  2. Fetch API

JSONPlaceholder API

Like the previous tutorial, we will use the JSONPlaceholder API. This API is free and a great way to experiment with making API calls.

We will make a GET request to https://jsonplaceholder.typicode.com/posts. You can visit this link and see all the data as an array of objects in the browser.

Using the HTTP Module

In Node.js, we don't have access to XHR objects or the XHR API. Node.js provides the HTTP module that we can use to make requests to a server and communicate with APIs.

Let's make a simple GET request to the JSONPlaceholder API using the HTTP module. Create a file named api-call.js and insert the following code into that file. This will be our Node.js script that will make an API call to JSONPlaceholder.

javascript
Copied! ⭐️
const http = require('http');

const options = {
  hostname: 'jsonplaceholder.typicode.com',
  path: '/posts',
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
  },
};

const getPosts = () => {
  let data = '';

  const request = http.request(options, (response) => {
    // Set the encoding, so we don't get log to the console a bunch of gibberish binary data
    response.setEncoding('utf8');

    // As data starts streaming in, add each chunk to "data"
    response.on('data', (chunk) => {
      data += chunk;
    });

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

  // Log errors if any occur
  request.on('error', (error) => {
    console.error(error);
  });

  // End the request
  request.end();
};

getPosts();

Assuming you have Node.js installed, you should be able to run the script using the following command: node api-call. That will execute the JavaScript file using the Node.js runtime. The script will make an API call to JSONPlaceholder and return an array of objects.

As you can probably tell, there's a lot of configuration and setup necessary to make an API call in Node.js versus in the browser with XHR objects. Multiple external libraries exist that abstract out a lot of setup and complexities for us. One such library is Axios, which we'll see in my next article.

In the code above, we are grabbing all posts at the /posts resource in the JSONPlaceholder API. We could have instead grabbed a single post by using this URL: https://jsonplaceholder.typicode.com/posts/1. The only difference is the /1 at the end of the URL.

Let's change our code a bit to grab only one item.

javascript
Copied! ⭐️
const http = require('http');

const options = {
  hostname: 'jsonplaceholder.typicode.com',
  path: '/posts/1', // we changed the path to only grab one post
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
  },
};

const getPosts = () => {
  let data = '';

  const request = http.request(options, (response) => {
    // Set the encoding, so we don't get log to the console a bunch of gibberish binary data
    response.setEncoding('utf8');

    // As data starts streaming in, add each chunk to "data"
    response.on('data', (chunk) => {
      data += chunk;
    });

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

  // Log errors if any occur
  request.on('error', (error) => {
    console.error(error);
  });

  // End the request
  request.end();
};

getPosts();

You should get back a single object instead. It'll probably contain some Latin. When creating dummy data, developers like to use Lorem ipsum as placeholder text.

json
Copied! ⭐️
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

In the example above, we were using http.request, but this method is used as a general function that can accept any of the four HTTP request methods: GET, POST, PUT, DELETE. We could have used http.get to always make the request with the GET HTTP method.

javascript
Copied! ⭐️
const http = require('http');

const getPosts = () => {
  let data = '';

  const request = http.get('http://jsonplaceholder.typicode.com/posts/1', (response) => {
    // Set the encoding, so we don't get log to the console a bunch of gibberish binary data
    response.setEncoding('utf8');

    // As data starts streaming in, add each chunk to "data"
    response.on('data', (chunk) => {
      data += chunk;
    });

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

  // Log errors if any occur
  request.on('error', (error) => {
    console.error(error);
  });

  // End the request
  request.end();
};

getPosts();

Now, let's look an example of making a POST request using the http module. The main difference is that we need to create a request body and write this to the request object.

javascript
Copied! ⭐️
const http = require('http');

// Create the request body
const postData = JSON.stringify({
  title: 'foo',
  body: 'bar',
  userId: 1,
});

const options = {
  hostname: 'jsonplaceholder.typicode.com',
  path: '/posts',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(postData),
  },
};

const makePost = () => {
  let data = '';

  const request = http.request(options, (response) => {
    response.setEncoding('utf8');

    response.on('data', (chunk) => {
      data += chunk;
    });

    response.on('end', () => {
      console.log(data);
    });
  });

  request.on('error', (error) => {
    console.error(error);
  });

  // Write data to the request body
  request.write(postData);

  request.end();
};

makePost();

Note, however, that this API is meant for testing purposes only. If you try changing data in the JSONPlaceholder API using a POST request, you likely won't see those changes applied when you perform a GET request to look at that data again.

HTTP vs HTTPS

When looking through the Node.js documentation, you may discover that there is both an HTTP module and HTTPS module. The HTTPS module is used for encrypting the communication between your script and the server using TLS/SSL and a certificate.

Using Fetch

The Fetch API wasn't available globally until version 18 of Node.js. In order to use fetch in earlier versions, most people downloaded a third party package such as node-fetch. The Fetch API is still considered experimental, so it might be better to stick with node-fetch in case you discover anything strange with the fetch method. The Fetch API in Node.js behaves very similar to the implementation in the browser.

Let's make an API call to the JSONPlaceholder API using the fetch method.

javascript
Copied! ⭐️
const getPost = (num) => {
  fetch(`https://jsonplaceholder.typicode.com/posts/${num}`)
    .then(response => response.json())
    .then(data => console.log(data));
};

getPost(1);

You can probably already tell that this API makes it much easier to make a GET request. There's less configuration we have to setup compared to the HTTP module. We also get the luxury of dealing with promises instead of callback functions. We simply get back the response wrapped in a promise and call the response.json() method to get the data from the JSONPlaceholder API.

If you wanted to make a POST request, we could have written the following code:

javascript
Copied! ⭐️
fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  body: JSON.stringify({
    title: 'foo',
    body: 'bar',
    userId: 1,
  })
})
  .then((response) => response.json())
  .then((json) => console.log(json));

If the POST request is successful, the JSONPlaceholder API will return the ID of the post that was updated.

json
Copied! ⭐️
{"id": 101}

Conclusion

We have now seen the two main ways to make API calls using JavaScript in Node.js. The HTTP module is much different from XHR objects, but the Fetch API code remains the same as the browser implementation.

Resources