fetch() In Node.js Core: Why You Should Care
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()?
The 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 requestsHeaders
class - deal with HTTP request/response headers instanceRequest
class - represents an outbound request instanceResponse
class - 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();
console.log(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.
- The
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!