How to use fetch in NodeJS
With the release of Node version 17.5 the fetch API is finally available as part of the core runtime. Let’s find out how to use it. See the official release notes here
Why is it a big deal?
The fetch API is a well documented interface for sending HTTP calls. JS developers will finally be able to use the same thing on both backend and frontend without the need to install additional dependencies as those always carry some level of security risks. Hopefully it will finally reduce the need to install axios, node-fetch, got, needle, superagent or some others.
It is available in most modern browsers for a long time now and basically is the go to library for many developers for frontend already. So when it comes to shared packages between the two sides, people can finally just use fetch, and don’t need to worry about running it on a server, or in a browser.
The fetch API offers a pretty simple, clean, promise based API as opposed to the callback based older http
and https
native libraries. Before 17.5 if you wanted to send an HTTP post request and wrap it into a promise call, you had to do something like this:
const https = require('https');function httpsPost(url, { body, ...options }) {
return new Promise((resolve, reject) => {
const req = https.request(url, {
method: 'POST',
...options,
}, res => {
const chunks = [];
res.on('data', data => chunks.push(data))
res.on('end', () => resolve(Buffer.concat(chunks)))
})
req.on('error',reject);
if(body) {
req.write(body);
}
req.end();
})
}async function test() {
const result = await httpsPost('https://vinoonmedium.requestcatcher.com/test', {
body: JSON.stringify({ hello: 'world' })
});
console.log(result.toString());
}test();
And it doesn’t even include response JSON parsing, proper header or status handling, or anything else. With fetch, you can call
async function test() {
const response = await fetch('https://vinoonmedium.requestcatcher.com/test', {
body: JSON.stringify({ hello: 'world' }),
method: 'post',
}); console.log(response.headers);
console.log(response.status);
console.log(await response.text());
}test();
Notice, we did not even had to require anything, as fetch is available globally, and you get all the juice response details out of the box! Fetch also offers a few response parsing methods like response.json()
, response.text()
that return a promise to your data to await, but you can also just use the response.body that is a ReadableStream.
How to run the above snippets
If you copy pasted the above code snippets that is using fetch()
into a .js file (let’s say index.js) and tried to execute it locally, you most likely got some error like this:
ReferenceError: fetch is not defined
Why did you get an error when a few lines above I claimed that fetch is available globally? Well, it is only an experimental feature available in NodeJS version 17.5 and above. First let’s make sure that you are using a version that supports this with
node -v
If you are already using a good version, you just need to pass in a flag that enables this new feature.
node --experimental-fetch index.js
And this should do the trick.
After the next major LTI release of NodeJS 18 I expect this feature to be available without the experimental flag, as the API is pretty well documented and I don’t expect it to change.
Thanks for reading! I hope you found this short tutorial interesting and feel free to follow for more stories from the Javascript world!