How to Create an HTTP Client with Core HTTP in Nodejs
Tags: programming, node, httpclient, corehttp
Published: 2023-12-04 01:09:20

This article will guide developers in creating an HTTP client with core HTTP in Nodejs - have a read!

Node.js comes bundled with an [http](https://nodejs.org/api/http.html) and an [https module](https://nodejs.org/api/https.html). These modules have functions to create an HTTP server so that a Node.js program can respond to HTTP requests. They can also make HTTP requests to other servers. This key functionality equips Node.js programmers to create modern, API-driven web applications with Node.js. As it’s a core module, you do not need to install any libraries to use it.


In this blog, you will use the https module to make HTTP requests to [JSON Placeholder](https://jsonplaceholder.typicode.com/), a fake [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer) for testing purposes. You will begin by making a **GET** request, the standard HTTP request to receive data. You will then look at ways to customize your request, such as adding headers. Finally, you will make **POST**, **PUT**, and **DELETE** requests so that you can modify data in an external server.

**Prerequisites**

- This tutorial requires that you have Node.js installed. Once installed, you will be able to access the https module that’s used throughout the tutorial. This tutorial uses Node.js version 10.19.0. To install Node.js on macOS follow the steps in [How To Install Node.js and Create a Local Development Environment on macOS](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-and-create-a-local-development-environment-on-macos).

- The methods used to send HTTP requests have a Stream-based API. In Node.js, streams are instances of event emitters. How you respond to data coming from a stream is the same as how you respond to data from events. 

Now that you're done setting up Nodejs, let us dive in!

**Step 1: Making a GET Request**
      When you interact with an API, you typically make **GET** requests to retrieve data from web servers. In this step, you’ll look at two functions to make GET requests in Node.js. Your code will retrieve a JSON array of user profiles from a publicly accessible API.
      The https module has two functions to make **GET** requests—the `get()` function, which can only make **GET** requests, and the `request()` function, which makes other types of requests. You will begin by making a request with the `get()` function.

**Making Requests with `get()`**
HTTP requests using the get() function have this format:

```
https.get(URL_String, Callback_Function) {
    Action
}
```
The first argument is a string with the endpoint you’re making the request to. The second argument is a callback function, which you use to handle the response.

   First, set up your coding environment. In your terminal, create a folder called **requests** to store all your Node.js modules for this guide:

`mkdir requests`

Now, enter the folder: 

`cd requests`

  Create and open a new file in a text editor. This tutorial will use nano as it’s available in the terminal:

`nano getRequestWithGet.js`

  Now, to make HTTP requests in Node.js, import the https module by adding the follow line:

**requests/getRequestWithGet.js** -> `const https = require('https');`

**Note:** Node.js has an http and an https module. They have the same functions and behave similarly, but https makes the requests through the Transport Layer Security (TLS/SSL). As the web servers you are using are available via HTTPS, you will use the https module. If you are making requests to and from URLs that only have HTTP, then you would use the http module.

  Now use the http object to make a GET request to the API to retrieve a list of users. You will use JSON Placeholder, a publicly available API for testing. This API does not keep a record of any changes you make in your requests. It simulates a real server, and returns mocked responses as long as you send a valid request.

 Write the following highlighted code in your text editor:

**requests/getRequestWithGet.js** 

```
-> const https = require('https');

let request = https.get('https://jsonplaceholder.typicode. com/users?_limit=2', (res) => { });
```
As mentioned in the function signature, the `get()` function takes two parameters. The first is the API URL you are making the request to in string format and the second is a callback to handle the HTTP response. To read the data from your response, you have to add some code in the callback.

HTTP responses come with a status code. A status code is a number that indicates how successful the response was. Status codes between 200 and 299 are positive responses, while codes between 400 and 599 are errors.

   For this request, a successful response would have a 200 status code. The first thing you’ll do in your callback will be to verify that the status code is what you expect. Add the following code to the callback function:

**requests/getRequestWithGet.js** : 

```
const https = require('https');
let request = https.get('https://jsonplaceholder.typicode.com/
users?_limit=2', (res) => {
if (res.statusCode !== 200) {
    console.error(`Did not get an OK from the server. Code: ${
res.statusCode}`);
    res.resume();
return; }
});
```
The response object that’s available in the callback has a statusCode property that stores the status code. If the status code is not 200, you log an error to the console and exit.

Note the line that has res.resume() . You included that line to improve performance. When making HTTP requests, Node.js will consume all the data that’s sent with the request. The res.resume() method tells Node.js to ignore the stream’s data. In turn, Node.js would typically discard the data more quickly than if it left it for garbage collection—a periodic process that frees an application’s memory.

Now that you’ve captured error responses, add code to read the data. Node.js responses stream their data in chunks. The strategy for retrieving data will be to listen for when data comes from the response, collate all the chunks, and then parse the JSON so your application can use it.
   Modify the request callback to include this code:

**requests/getRequestWithGet.js**: 

```
const https = require('https');
let request = https.get('https://jsonplaceholder.typicode.com/
users?_limit=2', (res) => {
if (res.statusCode !== 200) {
    console.error(`Did not get an OK from the server. Code: ${
res.statusCode}`);
    res.resume();
return; }
let data = '';
res.on('data', (chunk) => { data += chunk;
});
res.on('close', () => { console.log('Retrieved all data'); console.log(JSON.parse(data));
}); });
```

  You begin by creating a new variable data that’s an empty string. You can store data as an array of numbers representing byte data or a string. This tutorial uses the latter as it’s easier to convert a JSON string to a JavaScript object.

  After creating the data variable, you create an event listener. Node.js streams the data of an HTTP response in chunks. Therefore, when the response object emits a data event, you will take the data it received and add it to your data variable.

  When all the data from the server is received, Node.js emits a close event. At this point, you parse the JSON string stored in data and log the result to the console.
Your Node.js module can now communicate with the JSON API and log the list of users, which will be a JSON array of three users. However, there’s one small improvement you can make first.
  This script will throw an error if you are unable to make a request. You may not be able to make a request if you lose your internet connection, for example. Add the following code to capture errors when you’re unable to send an HTTP request:


**requests/getRequestWithGet.js** : `...
res.on('data', (chunk) => {
    data += chunk;
  });
res.on('close', () => { console.log('Retrieved all data'); console.log(JSON.parse(data));
}); });
request.on('error', (err) => {
console.error(`Encountered an error trying to make a reques
t: ${err.message}`);
});`

When a request is made but cannot be sent, the request object emits an error event. If an error event is emitted but not listened to, the Node.js program crashes. Therefore, to capture errors you add an event listener with the `on()` function and listen for error events. When you get an error, you log its message.

 That’s all the code for this file. Save and exit nano by pressing `CTRL+X`. Now execute this program with node:

`node getRequestWithGet.js`

Your console will display this response:

```
Output
Retrieved all data
[
{
id: 1,
    name: 'Leanne Graham',
    username: 'Bret',
    email: 'Sincere@april.biz',
    address: {
      street: 'Kulas Light',
      suite: 'Apt. 556',
      city: 'Gwenborough',
      zipcode: '92998-3874',
      geo: [Object]
    },
    phone: '1-770-736-8031 x56442',
    website: 'hildegard.org',
    company: {
      name: 'Romaguera-Crona',
      catchPhrase: 'Multi-layered client-server neural-net',
      bs: 'harness real-time e-markets'
} },
{
id: 2,
    name: 'Ervin Howell',
username: 'Antonette',
    email: 'Shanna@melissa.tv',
    address: {
      street: 'Victor Plains',
      suite: 'Suite 879',
      city: 'Wisokyburgh',
      zipcode: '90566-7771',
      geo: [Object]
    },
    phone: '010-692-6593 x09125',
    website: 'anastasia.net',
    company: {
      name: 'Deckow-Crist',
      catchPhrase: 'Proactive didactic contingency',
      bs: 'synergize scalable supply-chains'
} }
]
```

This means you’ve successfully made a `GET`request with the core Node.js library.
  The `get()` method you used is a convenient method Node.js provides because `GET` requests are a very common type of request. Node.js provides a `request()` method to make a request of any type. Next, this tutorial will examine how to make a `GET` request with `request()`.


**Making Requests with `request()`**

The `request()` method supports multiple function signatures. You’ll use
this one for the subsequent example:

```
https.request(URL_String, Options_Object, Callback_Function) {
    Action
}
```
  The first argument is a string with the API endpoint. The second argument is a JavaScript object containing all the options for the request. The last argument is a callback function to handle the response.

  Create a new file for a new module called **getRequestWithRequest.js:**

The code you will write is similar to the `getRequestWithGet.js` module you wrote earlier. First, import the `https` module:

**requests/getRequestWithRequest.js**: 

```
const https = require('https');
```

Next, create a new JavaScript object that contains a `method` key:

**requests/getRequestWithRequest.js**: 

```
const https = require('https');
const options = { method: 'GET'
};
```
The `method` key in this object will tell the `request()` function what HTTP method the request is using.

  Next, make the request in your code. The following codeblock highlights code that was different from the request made with the `get()` method. In your editor, enter all of the following lines:


**requests/getRequestWithRequest.js**: 

```
...
let request = https.request('https://jsonplaceholder.typicode.
com/users?_limit=2', options, (res) => { if (res.statusCode !== 200) {
    console.error(`Did not get an OK from the server. Code: ${
res.statusCode}`);
    res.resume();
return; }
let data = '';
res.on('data', (chunk) => { data += chunk;
});
res.on('close', () => { console.log('Retrieved all data'); console.log(JSON.parse(data));
}); });
request.end(); request.on('error', (err) => {
 console.error(`Encountered an error trying to make a reques
t: ${err.message}`);
});
```

To make a request using `request()`, you provide the URL in the first argument, an object with the HTTP options in the second argument, and a callback to handle the response in the third argument.
  The `options` variable you created earlier is the second argument, telling Node.js that this is a `GET` request. The callback is unchanged from when you first wrote it.

 You also call the `end()` method of the request variable. This is an important method that must be called when using the `request()` function. It completes the request, allowing it to be sent. If you don’t call it, the program will never complete, as Node.js will think you still have data to add to the request.
Save and exit nano with `CTRL+X`, or the equivalent with your text editor. Run this program in your terminal:

**node getRequestWithRequest.js**

You will receive this output, which is the same as the first module:

```
Output
Retrieved all data
[
{
id: 1,
    name: 'Leanne Graham',
    username: 'Bret',
    email: 'Sincere@april.biz',
    address: {
      street: 'Kulas Light',
      suite: 'Apt. 556',
      city: 'Gwenborough',
      zipcode: '92998-3874',
      geo: [Object]
    },
    phone: '1-770-736-8031 x56442',
    website: 'hildegard.org',
    company: {
      name: 'Romaguera-Crona',
      catchPhrase: 'Multi-layered client-server neural-net',
      bs: 'harness real-time e-markets'
} },
{
id: 2,
    name: 'Ervin Howell',
username: 'Antonette',
    email: 'Shanna@melissa.tv',
    address: {
      street: 'Victor Plains',
      suite: 'Suite 879',
      city: 'Wisokyburgh',
      zipcode: '90566-7771',
      geo: [Object]
    },
    phone: '010-692-6593 x09125',
    website: 'anastasia.net',
    company: {
      name: 'Deckow-Crist',
      catchPhrase: 'Proactive didactic contingency',
      bs: 'synergize scalable supply-chains'
} }
]

```

You have now used the `request()` method to make a `GET` request. It’s important to know this function as it allows you to customize your request in ways the `get()` method cannot, like making requests with other HTTP methods.
  Next, you will configure and customize your requests with the `request()` function

**Step 2: Configuring HTTP `request()` Options**

The `request()` function allows you to send HTTP requests without specifying the URL in the first argument. In this case, the URL would be contained with the options object, and the `request()` would have this function signature:

`https.request(Options_Object, Callback_Function) {
    Action
}`

In this step, you will use this functionality to configure your `request()` with the `options` object.

  Node.js allows you to enter the URL in the options object you pass to the request. To try this out, reopen the `getRequestWithRequest.js` file:

```
nano getRequestWithRequest.js
```
  Remove the URL from the request() call so that the only arguments are the options variable and the callback function:

**requests/getRequestWithRequest.js**:

```
const https = require('https');
const options = { method: 'GET',
};
let request = https.request(options, (res) => { ...
```

Now add the following properties to the options object:

**requests/getRequestWithRequest.js**: 

```
const https = require('https');
const options = {
host: 'jsonplaceholder.typicode.com', path: '/users?_limit=2',
method: 'GET'
};
let request = https.request(options, (res) => { ...
```

Instead of one string URL, you have two properties— `host` and `path`. The `host` is the domain name or IP address of the server you’re accessing. The path is everything that comes after the domain name, including query parameters (values after the question mark).
   The options object can hold other useful data that goes into a request. For example, you can provide request headers in the options. Headers typically send metadata about the request.
   When developers create APIs, they may choose to support different data formats. One API endpoint may be able to return data in JSON, CSV, or XML. In those APIs, the server may look at the Accept header to determine the correct response type.

   The Accept header specifies the type of data the user can handle. While the API being used in these examples only return JSON, you can add the `Accept` header to your request to explicitly state that you want JSON.
 
Add the following lines of code to append the `Accept` header:

**requests/getRequestWithRequest.js**:

```
const https = require('https');
const options = {
host: 'jsonplaceholder.typicode.com', path: '/users?_limit=2',
method: 'GET',
headers: {
    'Accept': 'application/json'
  }
};

```

  By adding headers, you’ve covered the four most popular options that are sent in Node.js HTTP requests: `host`, `path`, `method`, and `headers`. Node.js supports many more options; you can read more at the official Node.js docs for more information.

Enter CTRL+X to save your file and exit .
  Next, run your code once more to make the request by only using the options:

```
node getRequestWithRequest.js
```

The results will be the same as your previous runs:

```
Output
Retrieved all data
[
{
id: 1,
    name: 'Leanne Graham',
    username: 'Bret',
    email: 'Sincere@april.biz',
    address: {
      street: 'Kulas Light',
      suite: 'Apt. 556',
      city: 'Gwenborough',
      zipcode: '92998-3874',
      geo: [Object]
    },
    phone: '1-770-736-8031 x56442',
    website: 'hildegard.org',
    company: {
      name: 'Romaguera-Crona',
      catchPhrase: 'Multi-layered client-server neural-net',
      bs: 'harness real-time e-markets'
} },
{
id: 2,
    name: 'Ervin Howell',
username: 'Antonette',
    email: 'Shanna@melissa.tv',
    address: {
      street: 'Victor Plains',
      suite: 'Suite 879',
      city: 'Wisokyburgh',
      zipcode: '90566-7771',
      geo: [Object]
    },
    phone: '010-692-6593 x09125',
    website: 'anastasia.net',
    company: {
      name: 'Deckow-Crist',
      catchPhrase: 'Proactive didactic contingency',
      bs: 'synergize scalable supply-chains'
} }
]
```

As APIs can vary from provider to provider, being comfortable with the `options` object is key to adapting to their differing requirements, with the data types and headers being some of the most common variations.
  So far, you have only done GET requests to retrieve data. Next, you will make a `POST` request with Node.js so you can upload data to a server.


**Step 3: Making a POST Request**

When you upload data to a server or want the server to create data for you, you typically send a `POST `request. In this section, you’ll create a `POST` request in Node.js. You will make a request to create a new user in the `users` API.

Despite being a different method from GET, you will be able to reuse code from the previous requests when writing your `POST `request. However, you will have to make the following adjustments:

-Change the method in the `options` object to `POST` 
-Add a header to state you are uploading JSON
-Check the status code to confirm a user was created 
-Upload the new user’s data

To make these changes, first create a new file called `postRequest.js`. 
Open this file in nano or an alternative text editor:

`nano postRequest.js`

Begin by importing the `https` module and creating an `options` object:

**requests/postRequest.js**:

```
const https = require('https');
const options = {
host: 'jsonplaceholder.typicode.com', path: '/users',
method: 'POST',
headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8'
  }
};
```

You change the path to match what’s required for `POST` requests. You also updated the method to `POST`. Lastly, you added a new header in your options `Content-Type`. This header tells the server what type of data you are uploading. In this case, you’ll be uploading JSON data with UTF-8 encoding.

  Next, make the request with the `request()` function. This is similar to how you made `GET` requests, but now you look for a different status code than 200. Add the following lines to the end of your code:


**requests/postRequest.js**:

```
...
const request = https.request(options, (res) => {
if (res.statusCode !== 201) {
console.error(`Did not get a Created from the server. Cod
e: ${res.statusCode}`);
    res.resume();
return; }
let data = '';
res.on('data', (chunk) => { data += chunk;
});
res.on('close', () => { console.log('Added new user'); console.log(JSON.parse(data));
}); });
```

 The highlighted line of code checks if the status code is 201. The 201 status code is used to indicate that the server created a resource.

This `POST` request is meant to create a new user. For this API, you need to upload the user details. Create some user data and send that with your `POST` request:

**requests/postRequest.js**:

```
...
const requestData = {
name: 'New User',
username: 'TechContentMarketers', email: 'user@techcontentarketers.com', address: {
    street: 'North Pole',
    city: 'Murmansk',
    zipcode: '12345-6789',
  },
  phone: '555-1212',
  website: 'techcontentmarketers.com',
  company: {
    name: 'TechContentMarketers',
    catchPhrase: 'Welcome to TCM',
    bs: 'tech content creation agency'
} };
request.write(JSON.stringify(requestData));
```

You first created the `requestData` variable, which is a JavaScript object containing user data. Your request does not include an `id` field, as servers typically generate these while saving the new data.

  You next use the `request.write()` function, which accepts a string or buffer object to send along with the request. As your `requestData` variable is an object, you used the `JSON.stringify` function to convert it to a string.
  To complete this module, end the request and check for errors:

**requests/postRequest.js**:

```
...
request.end();
request.on('error', (err) => {
console.error(`Encountered an error trying to make a reques
t: ${err.message}`);
});

```

You must write data before you use the `end()` function. The end() function tells Node.js that there’s no more data to be added to the request and sends it.

Save and exit nano by pressing `CTRL+X`.
Run this program to confirm that a new user has been created:

`node postRequest.js`

The following output will be displayed:


```
Output
Added new user
{
  name: 'New User',
  username: 'TechContentMarketers',
  email: 'user@techcontentmarketers.com',
  address: { street: 'North Pole', city: 'Murmansk', zipcode:
 '12345-6789' },
  phone: '555-1212',
  website: 'techcontentmarketers.com',
  company: {
    name: 'TechContentMarketers',
    catchPhrase: 'Welcome to TCM',
    bs: 'tech content creation agency'
},
id: 11 }
```

The output confirms that the request was successful. The API returned the user data that was uploaded, along with the ID that was assigned to it.
  Now that you have learned how to make `POST` requests, you can upload data to servers in Node.js. Next, you will try out `PUT` requests, a method used to update data in a server.

**Step 4 — Making a PUT Request**

Developers make a `PUT` request to upload data to a server. While this may be similar to `POST` requests, `PUT` requests have a different function. `PUT` requests are idempotent—you can run a `PUT` request multiple times and it will have the same result.

   In practice, the code you write is similar to that of a `POST` request. You set up your options, make your request, write the data you want to upload, and verify the response.

   To try this out, you’re going to create a `PUT` request that updates the first user’s username.

  As the code is similar to the `POST` request, you’ll use that module as a base for this one. Copy the **postRequest.js**: into a new file, **putRequest.js**:

 

```
cd postRequest.js putRequest.js
```

Now open **putRequest.js** in a text editor:

```
nano putRequest.js
```
Make these highlighted changes so that you send a `PUT` request to `https://jsonplaceholder.typicode.com/users/1:`

**requests/putRequest.js**:

```
const https = require('https');
const options = {
host: 'jsonplaceholder.typicode.com', path: '/users/1',
method: 'PUT',
headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=UTF-8'
  }
};
const request = https.request(options, (res) => {
if (res.statusCode !== 200) {
console.error(`Did not get an OK from the server. Code: ${
res.statusCode}`);
    res.resume();
return; }
let data = '';
res.on('data', (chunk) => { data += chunk;
});
res.on('close', () => { console.log('Updated data'); console.log(JSON.parse(data));
}); });
const requestData = { username: 'digitalocean'
};
request.write(JSON.stringify(requestData));
request.end();
request.on('error', (err) => {
console.error(`Encountered an error trying to make a reques
t: ${err.message}`);
});
```

You first change the `path` and `method` properties of the `options` object. `path `in this case identifies the user that you are going to update. When you make the request, you check if the response code is 200, meaning that the request is OK. The data you are uploading now only contains the property
you are updating.

Save and exit nano with `CTRL+X`.
Now execute this Node.js program in your terminal:

```
node putRequest.js
```

This will be your output:

`Updated data
{ username: 'TechContentMarketers', id: 1 }`


You sent a `PUT` request to update a pre-existing user.

So far you have learned how to retrieve, add, and update data. To give us a full command of managing data via APIs, you’ll next make a `DELETE` request to remove data from a server.


**Step 5 — Making a DELETE Request**

The `DELETE` request is used to remove data from a server. It can have a request body, but most APIs tend not to require them. This method is used to delete an entire object from the server. In this section, you are going to delete a user using the API.

The code you will write is similar to that of a `GET` request, so use that module as a base for this one. 

Copy the **getRequestWithRequest.js** file into a new **deleteRequest.js** file:

```
cp getRequestWithRequest.js deleteRequest.js
```

Open `deleteRequest.js` with nano:

```
nano deleteRequest.js
```

Now modify the code at the highlighted parts, so you can delete the first user in the API:

**requests/putRequest.js**:

```
const https = require('https');
const options = {
host: 'jsonplaceholder.typicode.com', path: '/users/1',
method: 'DELETE',
headers: {
    'Accept': 'application/json',
  }
};
const request = https.request(options, (res) => {
if (res.statusCode !== 200) {
console.error(`Did not get an OK from the server. Code: ${
res.statusCode}`);
    res.resume();
return; }
let data = '';
res.on('data', (chunk) => { data += chunk;
});
res.on('close', () => {
console.log('Deleted user');
    console.log(JSON.parse(data));
  });
});
request.end();
request.on('error', (err) => {
console.error(`Encountered an error trying to make a reques
t: ${err.message}`);
});
```

For this module, you begin by changing the `path` property of the options object to the resource you want to delete—the first user. You then change the method to `DELETE`.

Save and exit this file by pressing `CTRL+X`.

  Run this module to confirm it works. Enter the following command in your terminal:

`node deleteRequest.js`

`Output
Deleted user
{}`

While the API does not return a response body, you still got a 200 response so the request was OK.

You’ve now learned how to make `DELETE` requests with Node.js core modules.


**Conclusion**

In this tutorial, you made `GET`, `POST`, `PUT`, and `DELETE` requests in Node.js. 

No libraries were installed; these requests were made using the standard ht tps module. While `GET` requests can be made with a `get()` function, all other HTTP methods are done via the `request()` method.

The code you wrote was written for a publicly available, test API. However, the way you write requests will work for all types of APIs.