Skip to content

Requests, headers, and bodies

FetchRequest is a FetchRequestInit plus required url: string. FetchRequestInit<BODY> extends native RequestInit, replacing headers with RequestHeaders and body with RequestBodyType; it adds timeout, urlParams, and abortController. Native credentials, cache, mode, redirect, integrity, and other supported Fetch options pass through.

For ordinary calls, pass a request object to the client method; call mergeRequest directly only when composing two configurations yourself. Use urlParams.path for template values and urlParams.query for the query string. body selects payload content, while resultExtractor belongs in the separate third method argument, not inside the request.

Request fields

Field/typeContract
RequestHeaders / RequestHeadersCapablePlain string-keyed record of string | undefined; not a native Headers instance.
RequestBodyTypeBodyInit | Record<string, any> | string | null; a missing body remains missing.
BaseURLCapableRequired baseURL: string; UrlParamsCapable supplies optional urlParams.
HttpMethodString enum GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE; platform restrictions still apply.
CONTENT_TYPE_HEADER'Content-Type'; ContentTypeValues.APPLICATION_JSON is 'application/json', TEXT_EVENT_STREAM is 'text/event-stream'.

Merge rules

mergeRequest(first, second): FetchRequestInit merges path and query records one level deep, and merges headers case-insensitively. The second request wins. For method, body, timeout, signal, and abortController, a nullish second value falls back to the first; body: null therefore does not clear an existing body in this helper. Other native fields follow object spread semantics. Empty-input shortcuts may return an original object when there are no headers; this is not a deep clone.

mergeRequestOptions(first?, second?) chooses the second non-nullish resultExtractor and attributes, then the first; its extractor fallback is Exchange. Attributes are replaced as a whole, not merged. mergeRecords(first?, second?) does a shallow second-wins merge and can return an existing record when only one exists. mergeRecordToMap(record?, map?) writes a record or map into the supplied map (or a new map) and returns that same map.

Header helpers

FunctionResult and mutation
getHeader(headers, name)Last case-insensitive matching value, or undefined; no mutation.
deleteHeader(headers, name)Removes all case variants; returns void.
setHeader(headers, name, value)Removes all variants, then sets the supplied spelling; undefined means delete.
mergeHeaders(...records)New record, later values win; later undefined removes an inherited header.

Body conversion

RequestBodyInterceptor runs before normal order-zero request interceptors. Strings and nullish bodies pass through. Blob, File, FormData, and URLSearchParams pass through after removing all Content-Type spellings so Fetch chooses the type/boundary. ArrayBuffer, typed-array/DataView views, and ReadableStream pass through without header adjustment. Other objects (including arrays) use JSON.stringify; JSON Content-Type is added only if absent. An explicit non-JSON Content-Type does not prevent JSON serialization. Circular data or BigInt may fail serialization and enter the error pipeline.

Streaming upload support and additional runtime-specific request fields remain the caller's responsibility. See pipeline ordering before inserting a body transformer.

Complete example

ts
import { Fetcher, mergeRequest, getHeader } from '@ahoo-wang/fetcher';

const client = new Fetcher({ baseURL: 'https://api.example.com' });
const request = mergeRequest(
  { headers: { Authorization: 'Bearer demo' }, timeout: 3000 },
  { headers: { authorization: undefined }, timeout: 0, body: { name: 'Ada' } },
);
const exchange = client.resolveExchange({
  ...request,
  url: '/users',
  method: 'POST',
});
console.assert(
  getHeader(exchange.request.headers, 'authorization') === undefined,
);
console.assert(exchange.request.timeout === 0);

Public symbols and source

SymbolImplementation
BaseURLCapablefetchRequest.ts:23
HttpMethodfetchRequest.ts:37
UrlParamsCapablefetchRequest.ts:48
CONTENT_TYPE_HEADERfetchRequest.ts:55
ContentTypeValuesfetchRequest.ts:57
RequestHeadersfetchRequest.ts:68
RequestHeadersCapablefetchRequest.ts:81
RequestBodyTypefetchRequest.ts:88
FetchRequestInitfetchRequest.ts:112
FetchRequestfetchRequest.ts:176
mergeRequestmergeRequest.ts:65
mergeRequestOptionsmergeRequest.ts:118
getHeaderrequestHeaders.ts:17
deleteHeaderrequestHeaders.ts:29
setHeaderrequestHeaders.ts:39
mergeHeadersrequestHeaders.ts:56
mergeRecordsutils.ts:42
mergeRecordToMaputils.ts:71

Package index

Released under the Apache License 2.0.