This package provides highly likely functional and easy-to-use abstraction atop of native http(s).request and http2.request.
- Fetch-alike
- Cool-beans π« config options (with defaults)
- Automatic HTTP/2 support (ALPN negotiation)
- Automatic or opt-in body parse (with non-UTF-8 charset decoding)
- Automatic and simplistic
Cookies
treatment (with built-in jar & ttl) - Automatic decompression (with opt-in body compression)
- Built-in streamable
FormData
interface - Support redirects & retries with fine-grained tune-ups
- Support all legit request body types (include blobs & streams)
- Support both CJS and ESM module systems
- Fully promise-able and pipe-able
- Zero dependencies
- Node.js
>= 18.13.0
npm install rekwest --save
import rekwest, { constants } from 'rekwest';
const {
HTTP2_HEADER_AUTHORIZATION,
HTTP2_HEADER_CONTENT_ENCODING,
HTTP2_METHOD_POST,
HTTP_STATUS_OK,
} = constants;
const url = 'https://somewhe.re/somewhat/endpoint';
const res = await rekwest(url, {
body: { celestial: 'payload' },
headers: {
[HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',
[HTTP2_HEADER_CONTENT_ENCODING]: 'br', // enables: body compression
/** [HTTP2_HEADER_CONTENT_TYPE]
* is undue for
* Array/Blob/File/FormData/Object/URLSearchParams body types
* and will be set automatically, with an option to override it here
*/
},
method: HTTP2_METHOD_POST,
});
console.assert(res.statusCode === HTTP_STATUS_OK);
console.info(res.headers);
console.log(res.body);
import { Readable } from 'node:stream';
import rekwest, {
constants,
Blob,
File,
FormData,
} from 'rekwest';
const {
HTTP2_HEADER_AUTHORIZATION,
HTTP2_HEADER_CONTENT_ENCODING,
HTTP2_METHOD_POST,
HTTP_STATUS_OK,
} = constants;
const blob = new Blob(['bits']);
const file = new File(['bits'], 'file.dab');
const readable = Readable.from('bits');
const fd = new FormData({
aux: Date.now(), // either [[key, value]] or kv sequenceable
});
fd.append('celestial', 'payload');
fd.append('blob', blob, 'blob.dab');
fd.append('file', file);
fd.append('readable', readable, 'readable.dab');
const url = 'https://somewhe.re/somewhat/endpoint';
const res = await rekwest(url, {
body: fd,
headers: {
[HTTP2_HEADER_AUTHORIZATION]: 'Bearer [token]',
[HTTP2_HEADER_CONTENT_ENCODING]: 'br', // enables: body compression
},
method: HTTP2_METHOD_POST,
});
console.assert(res.statusCode === HTTP_STATUS_OK);
console.info(res.headers);
console.log(res.body);
url
{string | URL} The URL to send the request tooptions
{Object} Extends http(s).RequestOptions along with extra http2.ClientSessionOptions & http2.ClientSessionRequestOptions and tls.ConnectionOptions for HTTP/2 attunesbaseURL
{string | URL} The base URL to use in cases whereurl
is a relative URLbody
{string | Array | ArrayBuffer | ArrayBufferView | AsyncIterator | Blob | Buffer | DataView | File | FormData | Iterator | Object | Readable | ReadableStream | SharedArrayBuffer | URLSearchParams} The body to send with the requestcookies
{boolean | Array<[k, v]> | Array<string> | Cookies | Object | URLSearchParams}Default: true
The cookies to add to the requestcookiesTTL
{boolean}Default: false
Controls enablement of TTL for the cookies cachecredentials
{include | omit | same-origin}Default: same-origin
Controls credentials in case of cross-origin redirectsdigest
{boolean}Default: true
Controls whether to read the response stream or simply add a mixinfollow
{number}Default: 20
The number of redirects to followh2
{boolean}Default: false
Forces the use of HTTP/2 protocolheaders
{Object} The headers to add to the requestmaxRetryAfter
{number} The upper limit ofretry-after
header. If unset, it will usetimeout
valueparse
{boolean}Default: true
Controls whether to parse response body or simply return a bufferredirect
{error | follow | manual}Default: follow
Controls the redirect flowsretry
{Object} Represents the retry optionsattempts
{number}Default: 0
The number of retry attemptsbackoffStrategy
{string}Default: interval * Math.log(Math.random() * (Math.E * Math.E - Math.E) + Math.E)
The backoff strategy algorithm that increases logarithmically. To fixate set value tointerval * 1
errorCodes
{string[]}Default: ['EAI_AGAIN', 'ECONNREFUSED', 'ECONNRESET', 'EHOSTDOWN', 'EHOSTUNREACH', 'ENETDOWN', 'ENETUNREACH', 'ENOTFOUND', 'EPIPE', 'ERR_HTTP2_STREAM_ERROR']
The list of error codes to retry oninterval
{number}Default: 1e3
The initial retry intervalretryAfter
{boolean}Default: true
Controlsretry-after
header receptivenessstatusCodes
{number[]}Default: [429, 500, 502, 503, 504]
The list of status codes to retry on
stripTrailingSlash
{boolean}Default: false
Controls whether to strip trailing slash at the end of the URLthenable
{boolean}Default: false
Controls the promise resolutionstimeout
{number}Default: 3e5
The number of milliseconds a request can take before terminationtrimTrailingSlashes
{boolean}Default: false
Controls whether to trim trailing slashes within the URL
- Returns: Promise that resolves to
extended http.IncomingMessage
or http2.ClientHttp2Stream which is respectively
readable and duplex streams
- if
digest: true
&parse: true
body
{string | Array | Buffer | Object} The body based on its content type
- if
digest: false
arrayBuffer
{AsyncFunction} Reads the response and returns ArrayBufferblob
{AsyncFunction} Reads the response and returns Blobbody
{AsyncFunction} Reads the response and returns Buffer ifparse: false
json
{AsyncFunction} Reads the response and returns Objecttext
{AsyncFunction} Reads the response and returns String
bodyUsed
{boolean} Indicates whether the response were read or notcookies
{undefined | Cookies} The cookies sent and received with the responseheaders
{Object} The headers received with the responsehttpVersion
{string} Indicates protocol version negotiated with the serverok
{boolean} Indicates if the response was successful (statusCode: 200-299)redirected
{boolean} Indicates if the response is the result of a redirectstatusCode
{number} Indicates the status code of the responsetrailers
{undefined | Object} The trailer headers received with the response
- if
The object to fulfill with default options.
The method to extend default options per instance.
import rekwest, { constants } from 'rekwest';
const {
HTTP_STATUS_OK,
} = constants;
const rk = rekwest.extend({
baseURL: 'https://somewhe.re',
});
const signal = AbortSignal.timeout(1e4);
const url = '/somewhat/endpoint';
const res = await rk(url, {
signal,
});
console.assert(res.statusCode === HTTP_STATUS_OK);
console.info(res.headers);
console.log(res.body);
The method with limited functionality to use with streams and/or pipes.
- No automata (redirects & retries)
- Pass
h2: true
in options to use HTTP/2 protocol- Use
ackn({ url: URL })
method in advance to check the available protocols
- Use
import fs from 'node:fs';
import { pipeline } from 'node:stream/promises';
import rekwest, {
ackn,
constants,
} from 'rekwest';
const {
HTTP2_METHOD_POST,
} = constants;
const url = new URL('https://somewhe.re/somewhat/endpoint');
const options = await ackn({ url });
await pipeline(
fs.createReadStream('/path/to/read/inlet.xyz'),
rekwest.stream(url, { ...options, method: HTTP2_METHOD_POST }),
fs.createWriteStream('/path/to/write/outlet.xyz'),
);
For more details, please check tests (coverage: >97%) in the repository.