Node.js v17.5 introduces support for
fetch() – a popular cross-platform HTTP client API that works in browsers and Web/Service Workers – as an experimental core feature.
fetch() support has been a long-requested addition by many, who want to write cross-platform HTTP request code and are familiar with the
fetch() API shape and call patterns. So much so that the
node-fetch module exists solely to backfill this functionality in Node.js. The good news is that going forward, an additional module will not be needed, as Node.js core will now support the API.
This post explores the
fetch() API and why this is an important addition you should consider using (one of the reasons rhymes with schmer-formance).
What is fetch()?
fetch() API provides a WHATWG standardized interface for fetching resources, usually over HTTP. It’s a promise-based client that supports many high-level HTTP features, while also focusing on the most common scenario: sending simplified HTTP requests. To those coming from the browser world, it is similar to
XMLHttpRequest, but standardized and with an expanded and more flexible feature set. One of the things that have held developers back is the relatively recent addition of this API to some browsers (looking at you, Android). That’s why the addition of
fetch() to Node.js is an exciting step toward a more standard HTTP stack across devices and platforms.
At its core, the API comprises of four interfaces
fetch()- the entry point used to initiate requests
Headersclass - deal with HTTP request/response headers instance
Requestclass - represents an outbound request instance
Responseclass - represents an incoming response instance
Putting these together, here is a trivial example:
const res = await fetch('https://dog.ceo/api/breeds/list/all');
const json = await res.json();
The good part about
fetch() being standardized is that most existing resources that pertain to the browser version will also work the same in the Node.js implementation, and there are a lot of great resources out there!
Why should you care?
There are two main reasons you may want to consider trying out
fetch() in Node.js:
- There is a lively ongoing conversation in the community about how to evolve Node’s HTTP stack in a way that’s familiar to client developers, but also works with the server programming model, how to move past the limitations of the current HTTP model that’s part of the core, and how to support HTTP/2-3 without over-burdening the user. This experimental core feature is the first step in that conversation, and it gives you an opportunity to try it out and get involved in the conversation.
fetch()implementation is based on Undici, a new fast, reliable, and spec-compliant HTTP/1.1 client that is now bundled in Node.js core. Because Undici does away with some dated HTTP primitives and builds directly on top of sockets, it can frequently deliver substantial improvements in latency and throughput over the existing implementation.
How do you get it?
First, be sure to update to Node 17.5 and run it using the
--experimental-fetch flag. You can then use the
fetch() global without needing any additional modules! We will update this post and share via @fusebito when this experimental feature graduates and becomes available without a flag.