HTTP Client in JavaScript: Making Requests Correctly in Node.js

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: Why Do You Need an HTTP Client in Node.js?

In modern web development, it is impossible to do without interacting with external services. Whether it's sending data to a server, fetching currency exchange rates, working with REST APIs, or integrating with cloud platforms — all of this requires the ability to send HTTP requests. In the Node.js environment, there are several approaches for this: from the built-in http module to popular third-party libraries such as axios and the native fetch.

In this article, we will break down how to properly organize an HTTP client in JavaScript (Node.js), which tools to choose for different tasks, and how to avoid common mistakes. You will learn how to handle responses, manage asynchronicity, and write clean, maintainable code.



Main Ways to Create HTTP Requests in Node.js

Node.js provides the developer with several options for working with HTTP. Let's look at three main ones: the built-in http module, the axios library, and the native fetch.



1. Built-in http/https Module

The lowest-level method. It gives you full control over the request but requires writing more code. It is suitable for cases where you need to minimize dependencies or work with non-standard protocols.

Example of a GET request using the https module:

const https = require('https');

function getUsers() { return new Promise((resolve, reject) => { https.get('https://jsonplaceholder.typicode.com/users', (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => resolve(JSON.parse(data))); }).on('error', reject); });}

getUsers().then(users => console.log(users[0].name));

Pros: no external dependencies, full control.
Cons: verbose code, need to wrap in Promise, manual stream management.



2. The axios Library

The most popular library for HTTP requests. It works both in the browser and in Node.js. It supports Promise, interceptors, automatic JSON parsing, and request cancellation.

Installation:

npm install axios

Example of a POST request with axios:

const axios = require('axios');

async function createPost() { try { const response = await axios.post('https://jsonplaceholder.typicode.com/posts', { title: 'HTTP Client in JavaScript', body: 'Making requests correctly', userId: 1 }); console.log('Post created:', response.data); } catch (error) { console.error('Error:', error.message); }}

createPost();

Pros: simple API, automatic JSON handling, interceptors, timeouts.
Cons: requires installation, library size (~14 KB gzip).



3. Native fetch (Node.js 18+)

Starting from Node.js version 18, fetch has become a built-in function. This unifies code between the browser and the server. However, older versions of Node.js will require a polyfill.

Example with fetch and async/await:

async function getUser(id) {  const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);  if (!response.ok) {    throw new Error(`HTTP error! status: ${response.status}`);  }  const user = await response.json();  return user;}

getUser(1).then(user => console.log(user.name));

Pros: native, no installation required, modern API.
Cons: not supported in Node.js < 18, no built-in timeout, requires manual status checking.



Proper Error Handling and Timeouts

One of the most common problems when working with HTTP clients is ignoring error handling. The network is unreliable, the server might respond with a 500 error or not respond at all

Blogs

Book Recommendations