Node.js Fetch API - Saving a Web Stream to a File
![Node.js Fetch API - Saving a Web Stream to a File](/content/images/size/w2000/2023/07/5902785747_97912ced36_k.jpg)
As of Node.js 18 the Fetch API is enabled by default. This is an exciting development that will allow you to use universal API between both Node and the browser for making REST API requests. I had to do some work with a REST API recently and rather than using the handy dandy Axios library that I've used previously, I decided to take the opportunity to learn the fetch API.
Everything was pretty simple to get started with (pro-tip you can right click a request in your browser dev tools and copy a request as fetch). But that was until I came to needing to download a file in response to a GET request. With Curl you can just use the --output parameter to output to a file, but how do you do this using the fetch API in node?
There are two types of streams in Node, the old [Node.js Streams](https://nodejs.dev/learn/nodejs-streams) that have been in Node for a long time and are used by Node.js built-in libraries like fs, and http. But now with the integration of the fetch API into Node.js there are now [Web Streams](https://nodejs.org/api/webstreams.html) as well which is what the Fetch API uses.
So you cannot just pass a Web Stream to a library like fs that uses Node Streams and have things work nicely. But the Node.js developers are kind and have provided methods built into Node.js to convert between a Node.js Stream and a Web Stream.
const readableNodeStream = nodeStream.Readable.fromWeb(response.body);
const fileStream = fs.createWriteStream('path/to/file.pdf');
return new Promise((resolve, reject) => {
readableNodeStream.pipe(fileStream);
readableNodeStream.on('error', reject);
fileStream.on('finish', resolve);
}