Adapter
The Adapter class is the backbone of Hyper Fetch's communication system. It abstracts the details of how requests are
executed, allowing you to swap between HTTP, GraphQL, Firebase, or any custom transport layer with ease. Adapters are
responsible for executing requests, mapping payloads and headers, handling query parameters, and integrating with the
request lifecycle—including progress tracking, cancellation, and error handling.
- Handles the network communication for all requests.
- Provides hooks for mapping headers, payloads, endpoints, and query parameters.
- Allows you to switch between HTTP, GraphQL, Firebase, and more by swapping adapters.
- Enables progress tracking, cancellation and error handling.
- Allows you to override default behaviors for advanced scenarios.
Initialization
By default, Hyper Fetch provides a unified HTTP adapter built on the native fetch API, which works in both browser and
Node.js environments (Node 18+). You can also create your own adapters to support other protocols or advanced use cases.
import { createClient } from "@hyper-fetch/core";
import { GraphqlAdapter } from "@hyper-fetch/graphql";
const client = createClient({
url: "https://api.example.com",
})
// Change the adapter to GraphQL
.setAdapter(GraphqlAdapter());
Quick Start
You can customize the adapter's behavior by using its configuration methods. For example, to set a custom header mapper:
client.adapter.setHeaderMapper((headers, config) => {
// Add custom logic for headers
return { ...headers, "X-Custom-Header": "value" };
});
Or to change how payloads are processed:
client.adapter.setPayloadMapper((payload, config) => {
// Transform payload before sending
return JSON.stringify(payload);
});
Available Methods
| Name | Description |
|---|---|
| This method allows to configure global defaults for the request configuration like method, auth, deduplication etc. |
| Set the configuration object passed as the second argument to the query params mapper. |
| Set the query params mapping function which get triggered before request get sent |
| Set the configuration object passed as the second argument to the payload mapper. |
| Set the request payload mapping function which gets triggered before request is send |
| Set a custom mapping for internal adapter errors before they are returned in the response. |
| Set the configuration object passed as the second argument to the header mapper. |
| Set the custom header mapping function |
| Set the fetcher function that performs the actual network request. Must be called before any request can be executed. |
| Set the configuration object passed as the second argument to the endpoint mapper. |
| Set the endpoint mapping function which transforms the endpoint string before the request is sent |
| Set a function that formats the endpoint string for display in devtools. |
| Set the default HTTP method used when a request does not specify one. |
| Set the default extra metadata attached to every request response (e.g., headers, status). |
| Set the adapter default options added to every sent request |
| Register a callback invoked once the adapter is initialized with a client. |
| Initialize the adapter with a client reference and set up logging. Called automatically when the client is created. |
| Execute a request through the adapter pipeline: maps endpoint/headers/payload, runs plugins, then calls the fetcher. |
| unstable_onInitializeCallback | |
| unstable_internalErrorMapping | Options Setters |
| unstable_getRequestDefaults | Get default request options for the request. |
| unstable_getAdapterDefaults | Get default adapter options for the request. |
| unstable_fetcher | Fetching function |
| unstable_devtoolsEndpointGetter | Get formatted endpoint name of the request. Helpful in displaying long endpoints like in case of graphql schemas etc. |
Features
-
Header Mapper
The header mapper determines how headers are set for each request. By default, it handles FormData and JSON content types automatically. You can override this logic for advanced scenarios.
client.adapter.setHeaderMapper((headers, config) => {
if (config.isAuth) {
return { ...headers, Authorization: `Bearer ${config.token}` };
}
return headers;
});
-
Payload Mapper
The payload mapper transforms the request body before it is sent. By default, it handles FormData and JSON. You can provide your own logic for custom serialization or encryption.
client.adapter.setPayloadMapper((payload, config) => {
// Encrypt or transform payload
return encryptPayload(payload);
});
-
Query Params Mapper
The query params mapper encodes query parameters for the request URL. You can customize the encoding or provide your own function.
client.adapter.setQueryParamsMapper((params, config) => {
// Custom query string encoding
return customStringify(params);
});
You can also set configuration for the query params mapper:
client.adapter.setQueryParamsMapperConfig({ arrayFormat: "bracket" });
-
Endpoint Mapper
The endpoint mapper allows you to transform or format the endpoint before the request is sent. Useful for multi-tenant APIs or dynamic routing.
client.adapter.setEndpointMapper((endpoint, config) => {
return `/v2${endpoint}`;
});
-
Defaults
Set adapter default options for all requests sent through this adapter:
// HTTP adapter options (based on native fetch RequestInit)
client.adapter.setAdapterDefaults((request) => ({
timeout: 5000,
credentials: "include",
}));
Each adapter has its own options. Check the API reference for the available options.
Set global defaults for request configuration (method, auth, deduplication, etc.).
client.adapter.setRequestDefaults((options) => ({ ...options, deduplicate: true }));
-
HyperFetch internal error mapping
Customize how Hyper Fetch internal errors are mapped and handled:
client.adapter.setInternalErrorMapping((error) => {
// Map or transform error
return { ...error, internal: true };
});
Customize how endpoints of your adapter are displayed in devtools. It allows for nice formatting of the endpoint.
client.adapter.setDevtoolsEndpointGetter((endpoint) => endpoint.toUpperCase());
-
Streaming
The default HTTP adapter supports response streaming via the native ReadableStream API. When a request is
configured with streaming: true, the adapter returns the raw response.body stream instead of buffering the entire
response. This is used internally by the useStream hook.
const streamRequest = client.createRequest()({
endpoint: "/api/chat/completions",
method: "POST",
options: { streaming: true },
});
const { data } = await streamRequest.send();
// data is a ReadableStream<Uint8Array>
const reader = data.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(decoder.decode(value, { stream: true }));
}
For React apps, use the useStream hook instead of manually consuming the stream.
It handles chunk accumulation, lifecycle management, and reactive re-renders automatically.
TypeScript Generics
When you create custom adapter, you need to specify the types for the requests templates. Each adapter may have different statuses, endpoints, params, additional data returned or required. With generic types you can handle specific cases to ensure absolute type-safety and flexibility across different protocols and use cases.
class Adapter<
AdapterOptions,
MethodType extends string,
StatusType extends number | string,
Extra extends Record<string, any>,
QueryParams = unknown,
// ...other generics
> {
/* ... */
}
Each option describe the type template for requests to be created within client using your adapter.
Refer to the API reference for detailed type parameters and usage examples.
