node-comfortv2.0.0

nc.http

An HTTP client on top of fetch: JSON by default, query objects, base URLs, timeouts, safe retries that respect Retry-After, typed errors, hooks, reusable clients and downloads with progress.

const { http } = require("@ix-xs/node-comfort");
import { request } from "@ix-xs/node-comfort/http";
const { data } = await http.get("https://api.github.com/repos/nodejs/node");

const api = http.create({ baseURL: "https://api.example.com/v1/", auth: { bearer: process.env.TOKEN } });
const { data: users } = await api.get("users", { query: { page: 2 } });
GuideExplanations and examples for nc.http.
Read the guide →

Functions

nc.http.request()

request<T = any>(url: string | URL, options?: HttpOptions): Promise<HttpResponse<T>>

Sends a request and resolves with the response, body already read. Throws an HttpError for error statuses, a TimeoutError when it's too slow and an AbortError when cancelled.

Parameters

NameTypeDescription
urlstring | URLAn absolute URL, or a path when baseURL is set.
optionsoptionalHttpOptions

Returns Promise<HttpResponse<T>>

Throws HttpError | TimeoutError | AbortError

Example

const res = await http.request("https://api.example.com/items/42", {
  method: "PUT",
  json: { name: "Lamp" },
  timeout: "10s",
  retry: { attempts: 5, statuses: [429, 503] },
});
res.data; // parsed JSON

nc.http.get()

get<T = any>(url: string | URL, options?: HttpOptions): Promise<HttpResponse<T>>

Sends a GET request.

Parameters

NameType
urlstring | URL
optionsoptionalHttpOptions

Returns Promise<HttpResponse<T>>

Example

const { data } = await http.get("https://api.example.com/users", { query: { page: 2, tags: ["a", "b"] } });

nc.http.post()

post<T = any>(url: string | URL, data?: unknown, options?: HttpOptions): Promise<HttpResponse<T>>

Sends a POST request. Objects, arrays, numbers and booleans go as JSON; strings, Buffers, FormData, Blobs and streams go as they are.

Parameters

NameType
urlstring | URL
dataoptionalunknown
optionsoptionalHttpOptions

Returns Promise<HttpResponse<T>>

Example

const { data: user } = await http.post("https://api.example.com/users", { name: "Ada" });
await http.post(uploadUrl, formData);

nc.http.put()

put<T = any>(url: string | URL, data?: unknown, options?: HttpOptions): Promise<HttpResponse<T>>

Sends a PUT request. The body works like in post().

Parameters

NameType
urlstring | URL
dataoptionalunknown
optionsoptionalHttpOptions

Returns Promise<HttpResponse<T>>

nc.http.patch()

patch<T = any>(url: string | URL, data?: unknown, options?: HttpOptions): Promise<HttpResponse<T>>

Sends a PATCH request. The body works like in post().

Parameters

NameType
urlstring | URL
dataoptionalunknown
optionsoptionalHttpOptions

Returns Promise<HttpResponse<T>>

nc.http.delete()

delete<T = any>(url: string | URL, options?: HttpOptions): Promise<HttpResponse<T>>

Sends a DELETE request.

Parameters

NameType
urlstring | URL
optionsoptionalHttpOptions

Returns Promise<HttpResponse<T>>

Example

await http.delete(`https://api.example.com/users/${id}`);

nc.http.download()

download(url: string | URL, destination: string, options?: HttpOptions): Promise<{ path: string; size: number; }>

Downloads to a file as a stream, so memory stays flat whatever the size. Folders are created, and a partial file is removed if it fails.

Parameters

NameType
urlstring | URL
destinationstring
optionsoptionalHttpOptions

Returns Promise<{ path: string, size: number }>: The absolute path and size in bytes.

Throws HttpError | TimeoutError | AbortError

Example

await http.download("https://example.com/video.mp4", "./downloads/video.mp4", {
  onDownloadProgress: ({ percent }) => bar.update(percent ?? 0),
});

nc.http.create()

create(defaults?: HttpOptions): HttpClient

Creates a client with default options. Options passed to each call are merged on top.

Parameters

NameType
defaultsoptionalHttpOptions

Returns HttpClient

Example

const github = http.create({
  baseURL: "https://api.github.com",
  auth: { bearer: process.env.GITHUB_TOKEN },
  hooks: { afterResponse: [(res) => nc.debug(res.status, res.url)] },
});
const { data: repo } = await github.get("/repos/nodejs/node");

nc.http.HttpErrorproperty

HttpError: typeof HttpError

Thrown by nc.http when the response status isn't 2xx (unless you pass throwHttpErrors: false), and for network failures (status 0).

Types

Import any of them in TypeScript with import type { HttpBody } from "@ix-xs/node-comfort", or in JavaScript with import("@ix-xs/node-comfort").HttpBody.

HttpBody

A request body.

type HttpBody = string | Buffer | Uint8Array | ArrayBuffer | URLSearchParams | FormData | Blob | ReadableStream | Readable

HttpClient

A client with its own defaults, from create().

PropertyTypeDescription
request<T = any>(url: string | URL, options?: HttpOptions) => Promise<HttpResponse<T>>Sends a request.
get<T = any>(url: string | URL, options?: HttpOptions) => Promise<HttpResponse<T>>Sends a GET request.
head<T = any>(url: string | URL, options?: HttpOptions) => Promise<HttpResponse<T>>Sends a HEAD request.
delete<T = any>(url: string | URL, options?: HttpOptions) => Promise<HttpResponse<T>>Sends a DELETE request.
post<T = any>(url: string | URL, data?: unknown, options?: HttpOptions) => Promise<HttpResponse<T>>Sends a POST request. Objects and arrays go as JSON.
put<T = any>(url: string | URL, data?: unknown, options?: HttpOptions) => Promise<HttpResponse<T>>Sends a PUT request. Objects and arrays go as JSON.
patch<T = any>(url: string | URL, data?: unknown, options?: HttpOptions) => Promise<HttpResponse<T>>Sends a PATCH request. Objects and arrays go as JSON.
download(url: string | URL, destination: string, options?: HttpOptions) => Promise<{ path: string; size: number; }>Saves a response to a file.
extend(defaults: HttpOptions) => HttpClientA new client with these defaults added.
defaultsReadonly<HttpOptions>

HttpHooks

Hooks to watch or change requests.

PropertyTypeDescription
beforeRequestoptional((config: HttpRequestConfig) => void | Promise<void>)[]Runs before each attempt. It can change the URL, headers or body.
afterResponseoptional((response: HttpResponse<any>, config: HttpRequestConfig) => void | HttpResponse<any> | Promise<void | HttpResponse<any>>)[]Runs after each response, before errors are thrown. It can return another response.
beforeRetryoptional((error: unknown, attempt: number, delay: number) => void | Promise<void>)[]Runs before waiting for a retry.

HttpMethod

An HTTP method.

type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | (string & {})

HttpOptions

Request options.

PropertyTypeDescription
methodoptionalHttpMethodDefaults to "GET".
baseURLoptionalstringPrefix for relative URLs.
headersoptionalRecord<string, string | undefined>Set a header to undefined to remove a default one.
queryoptionalURLSearchParams | QueryParamsAdded to the URL's own query string.
jsonoptionalunknownSent as JSON.
formoptionalRecord<string, string | number | boolean>Sent as a URL-encoded form.
bodyoptionalHttpBodySent as is: string, Buffer, FormData, stream...
authoptional{ bearer: string; } | { username: string; password: string; }Sets the authorization header.
timeoutoptionalstring | number | falseTime limit per attempt, like "10s". false turns it off. Defaults to 30 seconds.
retryoptionalnumber | false | HttpRetryOptionsNumber of attempts, false, or retry settings.
responseTypeoptional"json" | "buffer" | "auto" | "text" | "stream"How to read the body. "auto" reads JSON or text based on the content type, a Buffer otherwise.
throwHttpErrorsoptionalbooleanThrow an HttpError when the status isn't 2xx. Defaults to true.
signaloptionalAbortSignalCancels the request.
hooksoptionalHttpHooks
onDownloadProgressoptional((progress: { loaded: number; total: number | undefined; percent: number | undefined; }) => void)Called while the body downloads.
redirectoptional"error" | "follow" | "manual"Defaults to "follow".

HttpRequestConfig

A request as hooks see it.

PropertyTypeDescription
urlstringThe final URL, base URL and query included.
methodHttpMethod
headersRecord<string, string>Lower-cased names.
bodyHttpBody
attemptnumber1 for the first try.

HttpResponse

A response.

PropertyTypeDescription
statusnumber
statusTextstring
okbooleantrue for 2xx statuses.
headersRecord<string, string>Lower-cased names.
dataTThe body, already read (see responseType).
urlstringThe final URL, after redirects.
durationnumberIn ms, retries included.
attemptsnumberHow many attempts it took.

HttpRetryOptions

Retry settings.

PropertyTypeDescription
attemptsoptionalnumberTotal attempts, the first included. Defaults to 3 for methods that are safe to repeat, 1 for the others.
delayoptionalnumberWait before the first retry, in ms. Defaults to 300.
backoffoptionalnumberMultiplies the wait after each attempt. Defaults to 2.
maxDelayoptionalnumberLongest wait, Retry-After included. Defaults to 30 seconds.
statusesoptionalnumber[]Statuses worth retrying. Defaults to 408, 413, 429, 500, 502, 503 and 504.
methodsoptionalHttpMethod[]Methods allowed to retry. POST and PATCH aren't, by default, so nothing gets created twice.

QueryParams

Query string values. null and undefined are skipped, arrays repeat the key.

type QueryParams = Record<string, string | number | boolean | null | undefined | Array<string | number | boolean>>
node-comfort v2.0.0View the source