Fetch API in Node.js
Overview
The Fetch API has been used for making API requests on the client side for a while now, but due to some limitations, it could not be added to NodeJS. But, with the recent release of NodeJS v17.0, it was added as an experimental feature and it now comes bundled with the latest LTS(Long Term Support) version 18.0 which completes the long-awaited feature request of the NodeJS developer community. In this article, we'll discuss the NodeJS Fetch API in detail.
Introduction to Fetch API
Earlier, web developers used different complex ways to make asynchronous requests across the internet. To standardize this process, Internet Explorer introduced the XMLHttpRequest API in 1998 which was used to retrieve XML files over HTTP.
As XMLHttpRequest became more popular, it added support for some commonly used data transfer formats like HTML, JSON, and plain text. But with further advancements in web technologies, it became difficult to work with it, and Javascript frameworks like jQuery had to write custom implementations of XMLHttpRequest API to make its syntax and error handling easier.
The Fetch API was launched in 2015, and it quickly became the standard for modern web development. The most significant advantage of using the Fetch API was that it used promises which made the code cleaner and avoided the callback hell which was the primary concern in XMLHttpRequest API.
Though the Fetch API has been used in browsers for a while now, it wasn’t used in NodeJS because of some limitations. But various 3rd party packages like node-fetch had their custom implementations of the NodeJS Fetch API.
However, with Node v17.5, the fetch API was introduced as an experimental feature, and it is also available in the current LTS(Long Term Support) version v18.12
Difference from client-side Fetch API
- Support for cross-origin resource sharing and Content Security Policy is not present in NodeJS Fetch API as they are not needed in the context of servers.
- Also, there’s no concept of forbidden headers when making API calls from the server.
- Server side cookie store is not yet present in the NodeJS Fetch API.
- NodeJS Fetch API does not have server-side caching.
- Some of the request object methods like request.formData() are not present in server-side Fetch API.
Installation
The Fetch API comes bundled with NodeJS v17.5 and later. So, to use the Fetch API, you just need to upgrade to Node v17.5 or above. However, upgrading to Node v18 is recommended as it is the latest LTS (Long Term Support) and hence it is more stable. To check the version of NodeJS installed on your system, simply use
If it returns an error saying Command Not Found or a version number lower than v18, you can install the latest LTS version from the NodeJS official website.
How to Use Fetch?
To use the NodeJS Fetch API, we need to call the fetch() method as we do on the client side.
fetch(url[, options]);
The url parameter is the URL of the host from which we want to fetch the resource. The options parameter is optional, and it can be used to provide additional details like the request method, headers, and any data we want to send in the request body. The fetch() method returns a promise which gives us the entire response object with the JSON data, response headers, status code, etc. In case of some connectivity issues when our Node application is not able to connect to the external host, the fetch() call will throw an error, and we can handle it in our application.
Now, let’s use the NodeJS Fetch API to make a simple GET call and retrieve some data from a dummy API provider JSONPlaceholder. First, let's create a new directory fetch-api-demo, traverse to that directory, and initialize NPM in the directory using npm init.
-y here stands for "yes to all" and will select the default values for all the fields that npm needs for initialization
Now, create an index.js file and paste the following code:
In the above code, we make a GET call to the URL. The fetch() method returns a promise, which returns a response object once it is resolved. In the first then() block, we extract the JSON data from the response object which again returns a promise which gives the data returned by the API call, and we log it to the console. You can also use async/await for handling promises in which case your code would look as shown:
The Fetch API is an experimental feature that is enabled by default in Node v18, so we can directly run this file using node index.js. You may also see a warning mentioning that the Fetch API is an experimental feature.
Benefits of Using the Fetch API in Node.js
Since the Fetch API now comes bundled with Node, it is extremely beneficial for the developer community. Some of the benefits are:
Consistency across server and client
Frontend developers who have previously used the Fetch API on the client will feel very comfortable using the same syntax for making API requests on the server. Thus, it becomes simpler and more intuitive compared to using external packages for the same functionality.
Faster Implementation
The NodeJS Fetch API implementation is built on top of Undici which is an HTTP client and it is very fast and stable. Because of this, the Fetch API also performs better compared to other external packages.
No need for 3rd party packages
With the inbuilt Fetch API in NodeJS, other 3rd party packages like node-fetch, cross-fetch, etc. which served the same purpose will become obsolete. Now, developers don’t need to install any other 3rd party packages for making API requests.
How to Make HTTP Requests in Node.js With Fetch API?
We’ve already seen how to make GET calls using the NodeJS Fetch API. Let’s see another example where we make a POST request. As discussed earlier, the syntax of the fetch() method is as follows:
The options parameter here is an object where we can provide any additional information about our API request. There are various properties that we can pass in the options object, but here we’ll look at three of the most commonly used properties:
- method - It is used to define the method of our HTTP request like GET, POST, PUT, PATCH, etc. If this property is not provided, it is assumed to be a GET request.
- headers - It is used to pass any additional headers expected by the API server.
- body - It contains the body of our HTTP request.
Now, lets make a POST request to add a new item to our dummy JSONPlaceholder endpoint.
Here, we’re making an API request to the URL by passing the appropriate options to the fetch() method. We’re setting the header content-type to application/json to inform the server about the type of data to expect in the request body. We’re also converting our JSON object to a string by using JSON.stringify() as the Fetch API cannot directly handle JSON data.
We’re also wrapping our API request in a try/catch block to catch and handle any API failures. One thing to note here is that the NodeJS Fetch API considers only network connectivity issues as errors, and response status codes like 3xx/4xx/5xx are all considered non-error responses as the API request was successful. We need to handle such cases in the try block itself.
Looking for More Than Just JavaScript? Our Full Stack Developer Course Explores Advanced Front and Back-End Techniques. Enroll Now!
Advanced Usage
Streams
NodeJS Fetch API supports working with data streams. Sometimes, we might have to deal with large images, videos, or huge text files. In such cases, it is always desirable to break the data into smaller chunks and process it bit by bit. This can be easily achieved using the Fetch API:
Accessing Headers and other Metadata
The fetch() call returns a response object containing additional useful information about the response like the headers, status, etc. You can access these properties of the response objects as shown:
Extract Set-Cookie Header
Using the Fetch API, we can also access the response set-cookie header directly:
Post data using a file
We can also POST any file to a URL using the NodeJS Fetch API. Here, we’re using the fs module to read files from our local filesystem. Create a file named data.txt, enter some text in it and specify the relative path to the file in the fs.readFile() method.
Request cancellation with AbortSignal
We can cancel one or more ongoing API requests as and when required using AbortController. First, we need to create a new AbortController object:
Now, we need an instance of AbortSignal which can be used to communicate with the fetch request.
We can then define the condition for aborting the signal. For testing, let's say we want to abort the request after 100ms.
Now, we need to pass the instance of AbortSignal as an option to the fetch() method. This links the controller and the signal with the fetch request and aborts the signal when a predefined condition is met.
When you run the node file, you’ll see an AbortError stating that the request was aborted.
Axios vs Fetch API
- Using Axios, JSON data can be sent directly, but with Fetch API, we have to convert it to a string before sending it.
- Unlike Axios, Fetch API does not provide a way to monitor the progress of API requests.
- Axios internally converts API responses to JSON. But, with Fetch API, we need to call the JSON () method to get the JSON data.
- Fetch API does not support request interceptors while Axios supports it.
- Fetch API can accept responses as a data stream while Axios does not support it.
- In Axios, any API response status code other than 2xx is considered an error, and the request is rejected. But, with Fetch API, only requests that could not be completed because of some connectivity issues with the server are rejected.
- Axios natively supports request cancellation and timeout. But, with Axios, we have to use AbortController API to pass the signal to cancel ongoing API requests.
Unlock the full potential of Node.js with our expert-led Free Node.js course. Join today and get certified in Node.js!
Conclusion
- Making HTTP requests to communicate with the web server is the most common task in web development.
- Now that NodeJS officially comes bundled with the Fetch API, it simplifies this task and makes the overall development experience much better.
- NodeJS Fetch API can be used to make asynchronous web requests. We've also discussed the benefits, and differences between the NodeJS Fetch API and Axios along with some advanced usage of the Fetch API.