rekwest v5.2.2
The robust request library that humanity deserves 🌐
This package provides highly likely functional and easy-to-use abstraction atop of native http(s).request and http2.request.
Abstract
- 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
Prerequisites
- Node.js
>= 18.13.0
Installation
npm install rekwest --save
Usage
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);
API
rekwest(url[, options])
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
rekwest.defaults
The object to fulfill with default options.
rekwest.extend(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);
rekwest.stream(url[, options])
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.
3 days ago
3 days ago
2 months ago
5 months ago
6 months ago
6 months ago
7 months ago
7 months ago
11 months ago
11 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago