undici-fetch
❗️ Notice - this project is now apart of the core undici project 🚀
npm i undici-fetch
Built on Undici
Benchmarks
View all benchmarks here
API
The default export for this module is a fetch client instance fetch
. It uses the top level Undici.Request()
method. This project exposes the global dispatcher methods getGlobalDispatcher
and setGlobalDispatcher
if they need special configuration.
Exports
default: fetch
named exports:
fetch(resource, [init])
Default Method: - resource
string | Request | URL
- init
RequestInit
(optional)
Returns: Promise<Response>
// import and initialize all-at-once
const fetch = require('undici-fetch')()
// Promise Chain
fetch('https://example.com')
.then(res => res.json())
.then(json => console.log(json))
// Async/Await
const res = await fetch('https://example.com')
const json = await res.json()
Class: Headers
Represents a WHATWG Fetch Spec Headers Class
new Headers([init])
- init
Headers | Iterable<[string, string]> | string[] | Record<string, string>
(optional) - Initial header list to be cloned into the new instance
new Headers()
new Headers([
["undici", "fetch"]
])
new Headers([ 'undici', 'fetch' ])
const headers = new Headers({
"undici": "fetch"
})
new Headers(headers)
Instance Methods
Headers.append(name, value)
- name
string
- value
string
Returns: void
Non-destructive operation for adding header entries. When called multiple times with the same name, the values will be collected in a list and returned together when retrieved using Headers.get.
When value is not a string
, the value will be stringified.
const headers = new Headers()
headers.append('key', ['value', 'value2'])
headers.get('key') // -> 'value,value2'
headers.append('undici', 'fetch')
headers.get('undici') // -> 'fetch'
headers.append('foobar', 'fuzz')
headers.append('foobar', 'buzz')
headers.get('foobar') // -> 'fuzz, buzz'
Headers.delete(name)
- name
string
Returns: void
Removes a header entry. This operation is destructive and cannot be restored. Does not throw an error if the given name does not exist. Reminder that Headers.get will return null
if the name does not exist.
const headers = new Headers()
headers.append('undici', 'fetch')
headers.get('undici') // -> 'fetch'
headers.delete('undici')
headers.get('undici') // -> null
Headers.get(name)
- name
string
Returns: string | null
Retrieves a header entry. If the entry name has multiple values, they are returned as a string joined by ','
characters. If the name does not exist, this method returns null.
const headers = new Headers()
headers.append('undici', 'fetch')
headers.get('undici') // -> 'fetch'
headers.append('foobar', 'fuzz')
headers.append('foobar', 'buzz')
headers.get('foobar') // -> 'fuzz, buzz'
headers.get('nodejs') // -> null
Headers.has(name)
- name
string
Returns boolean
Checks for the existence of a given entry name.
const headers = new Headers()
headers.append('undici', 'fetch')
headers.has('undici') // -> true
Headers.set(name, value)
- name
string
- value
string
Returns: void
Destructive operation that will override any existing values for the given entry name. For a non-destructive alternative see Headers.append.
When value is not a string
, the value will be stringified.
const headers = new Headers()
headers.set('foobar', 'fuzz')
headers.get('foobar') // -> 'fuzz'
headers.set('foobar', 'buzz')
headers.get('foobar') // -> 'buzz'
Headers.values()
Returns: IteratableIterator<string>
Yields a list of header values combined and sorted by their respective keys.
const headers = new Headers()
headers.set('abc', '123')
headers.set('def', '456')
headers.set('ghi', '789')
headers.append('ghi', '012')
for (const value of headers.values()) {
console.log(value)
}
// -> '123'
// -> '456'
// -> '789, 012'
Headers.keys()
Returns: IteratableIterator<string>
Yields a sorted list of header keys.
const headers = new Headers()
headers.set('abc', '123')
headers.set('def', '456')
headers.set('ghi', '789')
headers.append('ghi', '012')
for (const name of headers.keys()) {
console.log(name)
}
// -> 'abc'
// -> 'def'
// -> 'ghi'
Headers.forEach(callback, [thisArg])
- callback
(value: string, key: string, iterable: Headers) => void
- thisArg
any
(optional)
Returns: void
A Headers class can be iterated using .forEach(callback, [thisArg])
.
Optionally a thisArg
can be passed which will be assigned to the this
context of callback.
The headers are returned in a sorted order, and values are combined on similar keys.
const headers = new Headers([['abc', '123']])
headers.forEach(function (value, key, headers) {
console.log(key, value)
})
// -> 'abc', '123'
Headers[Symbol.iterator]
Returns: Iterator<[string, string]>
A Headers class instance is iterable. It yields each of its entries as a pair where the first value is the entry name and the second value is the header value. They are sorted by name or otherwise referred to as the header key.
const headers = new Headers()
headers.set('abc', '123')
headers.set('def', '456')
headers.set('ghi', '789')
headers.append('ghi', '012')
for (const [name, value] of headers) {
console.log(name, value)
}
// -> 'abc', '123'
// -> 'def', '456'
// -> 'ghi', '789, 012'
Headers.entries()
Returns: IteratableIterator<[string, string]>
Yields a list of headers sorted and combined by key.
const headers = new Headers()
headers.set('abc', '123')
headers.set('def', '456')
headers.set('ghi', '789')
headers.append('ghi', '012')
for (const entry of headers.entries()) {
console.log(entry)
}
// -> 'abc', '123'
// -> 'def', '456'
// -> 'ghi', '789, 012'
Class: Request
Implemets: BodyMixin
Represents a WHATWG Fetch Spec Request Class
new Request(input, [init])
- input
Request | string | URL
- init
object
(optional)- method
string
(optional) - Defaults to'GET'
- headers
Headers | HeadersInit
(optional) - body
AsyncIterable | Iterable | null | undefined
(optional)- keepalive
boolean
(optional) - redirect
string
(optional) - integrity
string
(optional) - signal
AbortSignal
(optional)
- keepalive
- method
Creates a new Request
object. The resulting instance can be passed directly to the fetch method. The input string will be transformed into a Node.js URL instance.
const request = new Request('https://example.com', {
method: 'POST',
body: 'undici-fetch'
})
const res = await fetch(request)
Instance Properties:
Request.url
URL
A Node.js URL Class instance representing the destination of the Request instance
Request.method
string
A property representing the type of the Request instance. Will be normalized to uppercase format and validated as one of http.METHODS
.
Request.headers
Headers
A Headers class instance representing the Headers instance for the request instance.
Request.redirect
string
Request.integrity
string
Request.keepalive
boolean
Request.signal
AbortSignal
Instance Methods:
Request.clone()
Returns: Request
Will throw an Error
if the current instance Responce.bodyUsed
is true
. Returns a new Request instance based on the existing instance.
const request = new Request('https://example.com')
const newRequest = request.clone()
console.log(newRequest.url) // => 'https://example.com'
Class: Response
Extends: Body
Represents a WHATWG Fetch Spec Response Class
new Response(body, [init])
- body
AsyncIterable | Iterable | null | undefined
- init
object
(optional)- status
number
(optional) - Defaults to200
- statusText
string
(optional) - Defaults to''
- headers
Headers | HeadersInit
(optional)
- status
Creates a new Response
object. This is the result resolved from a successful fetch()
call. Remember that this class extends from Body so you can use methods such as .text()
and .json()
.
const response = new Response('undici-fetch')
if (response.ok) {
const text = await response.text()
console.log(text) // -> 'undici-fetch'
}
Instance Properties
Response.headers
Headers
A property representing a Headers instance for the response.
Response.ok
boolean
A property representing if the response is ok. A Response is considered ok if the status
is between 200 and 299 inclusive.
Response.status
number
A property representing the status code of the response.
Response.statusText
string
A property representing the status of the response instance. If returned from fetch()
, it will be based on http.STATUS_CODES
.
Response.type
string
Defaults to 'default'
. A property representing the type of response instance. Currently only used to indicate an error response from Response.error()
.
Instance Methods
Response.clone()
Returns: Response
Will throw an Error
if the current instance Responce.bodyUsed
is true
.
Static Methods
Response.error()
Returns: Response
Generates a Response instance with type
set to 'error'
and a body
set to null
.
const errorResponse = Response.error()
Response.redirect(url, status)
- url
string
- The redirect location--will be assigned to a'location'
header - status
number
- Must be one of: 301, 302, 303, 307, or 308
Returns: Response
const redirectResponse = Response.redirect('https://example.com', 301)
Function: BodyMixin
Represents a WHATWG Fetch Spec Body Mixin.
Use the mixin by called BodyMixin
with the prototype of an object.
class Response {
constructor (body) {
this[kBody] = body
}
}
BodyMixin(Response.prototype)
const response = new Response('undici-fetch')
response.body // -> ControlledAsyncIterable from input 'undici-fetch'
Properties
body
ControlledAsyncIterable | null
A property representing the payload of the instance. ControlledAsyncIterable
is a mock WHATWG Readable Stream. It implements the disturbed
property so that the Fetch api can operate accordingly.
bodyUsed
boolean
A property representing the consumption state of the instance. Do not confuse this property with the Node.js stream state. This property is used by the other instance methods for indicating to other parts of the API if the body has been consumed or not.
Methods
arrayBuffer()
Returns: Promise<Buffer>
Returns the body
content as a Node.js Buffer instance.
const response = new Response('undici-fetch')
const buf = await response.arrayBuffer()
console.log(buf instanceof Buffer) // -> true
console.log(buf.toString('utf8')) // -> 'undici-fetch'
blob()
Returns: never
Currently, this implementation does not support returning content as a blob. Calling this method will throw an error. This may change in future API updates.
const response = new Response('undici-fetch')
try {
await response.blob()
} catch (err) {
console.log(err.message) // -> 'Response.blob() is not supported yet by undici-fetch'
}
formData()
Returns: never
Currently, this implementation does not support returning content as a blob. Calling this method will throw an error. This may change in future API updates.
const response = new Response('undici-fetch')
try {
await response.formData()
} catch (err) {
console.log(err.message) // -> 'Response.formData() is not supported yet by undici-fetch'
}
json()
Returns: Promise<any>
Returns the body
content as a JSON object.
const content = JSON.stringify({ undici: 'fetch' })
const response = new Response(content)
const data = await response.json()
console.log(data) // -> { undici: 'fetch' }
text()
Returns: Promise<string>
Returns the body
content as a UTF-8 string.
const response = new Response('undici-fetch')
const text = await response.text()
console.log(text) // -> 'undici-fetch'
TypeScript
Similar to Undici, this module ships with its own TypeScript definitions. Make sure to install @types/node
as well.
Spec Omissions
Fetch is a browser API, but this library is written in Node.js. We try to be as spec compliant as possible; however, some aspects just cannot be recreated on the server. All Fetch WHATWG Spec omissions are detailed here. Each part should have a summary of the omission, plus links to relevant spec section and additional documentation.
Entries in this section have been considered for the implementation and explicitly ommitted. If you do not find an aspect of the Fetch API listed here that is also missing from the implementation, open an issue describing the feature request.
CORS
Any CORS-related aspects of the Fetch api has been omitted from this implementation.