Class: Request

HTTP client with interceptors, timeout, retry, cache, deduplication, and download progress.

Basic usage

const api = new Request('https://api.example.com')

// Directly awaitable
const user = await api.get<User>('/users/1')

// Lifecycle callbacks
await api.get('/users', {
  onSuccess: setUsers,
  onError: toast.error,
  onFinally: () => setLoading(false),
})

Composable best practice

Prefer small focused instances over one instance with all interceptors:

// ── Building blocks (pure functions, reusable) ──
const addAuth: RequestInterceptor = (config) => ({
  ...config,
  headers: { ...config.headers, Authorization: `Bearer ${getToken()}` }
})
const addLang: RequestInterceptor = (config) => ({
  ...config,
  headers: { ...config.headers, 'Accept-Language': 'zh-CN' }
})

// ── Compose: each instance handles one concern ──
const authApi = new Request('https://api.example.com')
authApi.useRequestInterceptor(addAuth)
authApi.useRequestInterceptor(addLang)

const publicApi = new Request('https://open.api.com')

// ── Or use per-request interceptors ──
api.get('/users', {}, {
  requestInterceptors: [addAuth],
  onSuccess: setUsers,
})

Constructors

Constructor

new Request(baseUrl?): Request

Parameters

baseUrl?

string = ''

Returns

Request

Methods

clearCache()

clearCache(): void

Clear the in-memory response cache.

Returns

void


delete()

delete<T>(url, params?, config?): RequestHandle<T>

Type Parameters

T

T = unknown

Parameters

url

string

params?

Record<PropertyKey, any>

config?

RequestConfig = {}

Returns

RequestHandle<T>


get()

get<T>(url, params?, config?): RequestHandle<T>

Type Parameters

T

T = unknown

Parameters

url

string

params?

Record<PropertyKey, any>

config?

RequestConfig = {}

Returns

RequestHandle<T>


patch()

patch<T>(url, data?, config?): RequestHandle<T>

Type Parameters

T

T = unknown

Parameters

url

string

data?

unknown

config?

RequestConfig = {}

Returns

RequestHandle<T>


post()

post<T>(url, data?, config?): RequestHandle<T>

Type Parameters

T

T = unknown

Parameters

url

string

data?

unknown

config?

RequestConfig = {}

Returns

RequestHandle<T>


put()

put<T>(url, data?, config?): RequestHandle<T>

Type Parameters

T

T = unknown

Parameters

url

string

data?

unknown

config?

RequestConfig = {}

Returns

RequestHandle<T>


request()

request<T>(url, config?): RequestHandle<T>

Type Parameters

T

T = unknown

Parameters

url

string

config?

RequestConfig = {}

Returns

RequestHandle<T>


sse()

sse<T>(url, config?): RequestHandle<T>

Create an SSE (Server-Sent Events) connection.

Uses Fetch API under the hood, so it supports:

  • Custom headers (unlike native EventSource)
  • POST requests
  • All HTTP methods

Type Parameters

T

T = unknown

Parameters

url

string

config?

Omit<RequestConfig, "sse"> & SSECallbacks = {}

Returns

RequestHandle<T>

Example

const api = new Request('https://api.example.com')

// GET SSE (default)
const handle = api.sse('/events', {
  onMessage: (event) => console.log(event.data),
  onError: (err) => console.error(err),
})

// POST SSE with data
const handle = api.sse('/chat/completions', {
  method: 'POST',
  data: { prompt: 'Hello' },
  onMessage: (event) => {
    const parsed = JSON.parse(event.data)
    console.log(parsed)
  },
})

// Cancel the connection
handle.abort()
```n

***

### useErrorInterceptor()

> **useErrorInterceptor**(`interceptor`): () => `void`

#### Parameters

##### interceptor

[`ErrorInterceptor`](../types/ErrorInterceptor.md)

#### Returns

() => `void`

***

### useRequestInterceptor()

> **useRequestInterceptor**(`interceptor`): () => `void`

#### Parameters

##### interceptor

[`RequestInterceptor`](../types/RequestInterceptor.md)

#### Returns

() => `void`

***

### useResponseInterceptor()

> **useResponseInterceptor**\<`T`, `U`\>(`interceptor`): () => `void`

#### Type Parameters

##### T

`T` = `unknown`

##### U

`U` = `unknown`

#### Parameters

##### interceptor

[`ResponseInterceptor`](../types/ResponseInterceptor.md)\<`T`, `U`\>

#### Returns

() => `void`