@xirang/request
v1.0.0
Published
HTTP request utilities for xirang tools project
Readme
@xirang/request
xirang 工具项目的 HTTP 请求库,基于 axios 构建,支持插件化扩展、多传输层与常见请求场景。
安装
pnpm add @xirang/request快速开始
xirang 业务场景(推荐)
内置 token / app_id 注入与 { code, data } 响应解包,适用于 xirang 各应用:
import { createRequest } from '@xirang/request';
const client = createRequest({
baseURL: '/api',
errorNotify(code, message) {
console.error(code, message);
},
});
// 通用请求(studio 等项目中的常见用法)
export const http = client.request;
interface User {
id: string;
name: string;
}
const users = await http<User[]>('/users', {
method: 'GET',
params: { page: 1 },
});纯净客户端
不含 xirang 业务逻辑,适合通用场景或自定义插件:
import { createClient } from '@xirang/request';
const client = createClient({
baseURL: 'https://api.example.com',
timeout: 10_000,
});
const users = await client.get<User[]>('/users', { params: { page: 1 } });
await client.post('/users', { name: '张三' });
await client.patch('/users/1', { name: '李四' });
await client.delete('/users/1');架构
传输层 (axios / fetch / http2)
↓
核心客户端 (createClient)
↓
插件层 (retry / cache / dedupe / 自定义)
↓
预设层 (xirangPreset — token / 响应解包)创建实例
createRequest
含 xirang 业务预设:
import { createRequest } from '@xirang/request';
const client = createRequest({
baseURL: '/api',
timeout: 10_000,
errorNotify: (code, message) => { /* toast 通知 */ },
});
await client.get<User[]>('/users', { params: { page: 1 } });
await client.request<User>('/users', { method: 'GET', params: { page: 1 } });createClient
无业务预设,通过插件组合能力:
import {
createClient,
xirangPreset,
retryPlugin,
cachePlugin,
createMemoryCacheStore,
} from '@xirang/request';
const client = createClient({
baseURL: '/api',
transport: 'fetch', // 'axios' | 'fetch' | 'http2'
plugins: [
cachePlugin({ ttl: 60_000, store: createMemoryCacheStore() }),
retryPlugin({ times: 3, delay: 1000, backoff: 2 }),
xirangPreset({ errorNotify: (code, msg) => console.error(code, msg) }),
],
dedupe: { methods: ['GET'] }, // 并发去重,设为 false 可禁用
});插件数组中越靠前越靠近传输层。推荐顺序:
cache → retry → xirangPreset。
请求方法
| 方法 | 说明 |
|------|------|
| request(url, options) | 通用请求 |
| get / post / put / patch / delete | REST |
| head / options | HTTP 探测 |
| upload(url, data, options?) | 文件上传(FormData / multipart) |
| download(url, options?) | 文件下载(blob / stream 等) |
| graphql(url, query, variables?, options?) | GraphQL |
| postForm(url, data, options?) | application/x-www-form-urlencoded |
// 上传
await client.upload('/upload', formData, {
onUploadProgress: (e) => console.log(e.loaded / e.total!),
});
// 下载
const blob = await client.download<Blob>('/file.pdf', {
responseType: 'blob',
onDownloadProgress: (e) => console.log(e.loaded),
});
// GraphQL
const data = await client.graphql<{ user: User }>(
'/graphql',
`query GetUser($id: ID!) { user(id: $id) { name } }`,
{ id: '1' },
);
// 表单
await client.postForm('/login', { username: 'admin', password: '123' });插件
retryPlugin — 失败重试
import { retryPlugin } from '@xirang/request';
retryPlugin({
times: 3, // 最大重试次数,默认 3
delay: 1000, // 初始延迟(ms),默认 1000
backoff: 2, // 退避系数,默认 2
statuses: [408, 429, 500, 502, 503, 504],
retryOn: (error, attempt) => true, // 自定义重试条件
});cachePlugin — GET 缓存
import { cachePlugin, createMemoryCacheStore } from '@xirang/request';
const store = createMemoryCacheStore();
cachePlugin({
ttl: 60_000, // 缓存有效期(ms),默认 60_000
methods: ['GET'], // 参与缓存的方法
store, // 自定义存储
});并发去重
默认对 GET 请求启用:相同 method + url + params 的进行中请求共享同一个 Promise。
import { withDedupe, clearDedupeCache } from '@xirang/request';
// 通过 createClient 配置
createClient({ dedupe: { methods: ['GET'] } });
createClient({ dedupe: false }); // 禁用SSE 流式请求
import { createSSE, Stream } from '@xirang/request/sse';
// 拉取 SSE 流
for await (const event of await createSSE('/api/chat/stream')) {
console.log(event.data);
}
// 解析已有 ReadableStream
const stream = Stream({ readableStream: response.body! });
for await (const event of stream) {
console.log(event);
}子路径导出
| 路径 | 内容 |
|------|------|
| @xirang/request | 主入口 |
| @xirang/request/fetch | Fetch 中间件 + createFetchRequest |
| @xirang/request/http2 | createHttp2Request(Node.js,实验性) |
| @xirang/request/sse | Stream + createSSE |
| @xirang/request/graphql | GraphQL 工具函数 |
| @xirang/request/form | 表单编码工具 |
| @xirang/request/presets/xirang | xirang 业务预设 |
// fetch 适配器
import { createFetchRequest } from '@xirang/request/fetch';
const client = createFetchRequest({ baseURL: '/api' });
// HTTP/2(Node.js)
import { createHttp2Request } from '@xirang/request/http2';
const client = createHttp2Request({ baseURL: 'https://api.example.com' });
// 原生 fetch 中间件
import { Fetch } from '@xirang/request/fetch';
const response = await Fetch('/api/data', {
middlewares: {
onRequest: async (...args) => args,
onResponse: async (res) => res,
},
});API 参考
createRequest(config?: CreateRequestConfig)
创建含 xirang 预设的请求实例。
interface CreateRequestConfig extends ClientConfig {
errorNotify?: (code: number, message: unknown) => void;
}createClient(config?: ClientConfig)
创建插件化请求客户端。
interface ClientConfig extends AxiosRequestConfig {
transport?: 'axios' | 'fetch' | 'http2';
plugins?: RequestPlugin[];
dedupe?: DedupeOptions | false;
httpVersion?: 1 | 2;
http2Options?: Http2Options;
}RequestInstance
interface RequestInstance {
instance: AxiosInstance;
request: <T>(url: string, options?: RequestMethodOptions) => Promise<T>;
get: <T>(url: string, options?) => Promise<T>;
post: <T>(url: string, data?, options?) => Promise<T>;
put / patch / delete / head / options: ...;
upload: <T>(url, data, options?) => Promise<T>;
download: <T>(url, options?) => Promise<T>;
graphql: <T>(url, query, variables?, options?) => Promise<T>;
postForm: <T>(url, data, options?) => Promise<T>;
}RequestPlugin
interface RequestPlugin {
onRequest?: (config) => config | Promise<config>;
onRequestError?: (error) => unknown;
onResponse?: (response) => response | Promise<response>;
transformResponse?: (response) => unknown;
onResponseError?: (error) => unknown;
wrapExecutor?: <T>(config, executor) => Promise<T>;
}特性
- 分层架构 — 传输层 / 核心 / 插件 / 预设,按需组合
- xirang 开箱即用 — token、app_id、响应解包内置
- REST 全覆盖 — GET / POST / PUT / PATCH / DELETE / HEAD / OPTIONS
- 文件传输 — upload / download,支持进度回调
- GraphQL / Form — 内置 graphql、postForm 方法
- SSE 流式 — Server-Sent Events 解析与拉流
- 插件扩展 — retry(指数退避)、cache(GET 缓存)、dedupe(并发去重)
- 多传输层 — axios(默认)、fetch、http2(Node.js)
开发
使用 tsdown 打包,配置见 tsdown.config.ts。
pnpm install
pnpm build # tsdown
pnpm dev # tsdown --watch
pnpm lint
pnpm check-types
pnpm test
pnpm test:run
pnpm test:coverage许可证
MIT
