Core Docs

@skyroc/axios

基于 Axios 的请求客户端工厂,提供类型安全的请求实例、业务错误处理、Token 刷新、请求取消等能力

概述

@skyroc/axios 是一个基于 Axios 的请求客户端工厂包,采用工厂函数 + 钩子策略的设计模式,在原生 Axios 之上提供:

  • 两种请求风格createRequest(抛异常)和 createFlatRequest(Result 风格,不抛异常)
  • 业务错误与 HTTP 错误的统一处理
  • 请求/响应拦截器钩子onRequestisBackendSuccessonBackendFailonErrortransform
  • 自动请求 ID(每个请求携带唯一的 X-Request-Id
  • 请求取消管理cancelAllRequest
  • 可选的 axios-retry 重试机制
  • 响应类型推导jsonblobtextarrayBuffer 等)

架构

用户调用 request(config)


┌─────────────────────────┐
│   请求拦截器             │
│  • 生成 X-Request-Id    │
│  • 挂载 AbortController │
│  • 调用 onRequest 钩子   │
└────────────┬────────────┘

      Axios 发送请求


┌─────────────────────────┐
│   响应拦截器             │
│  • transformResponse    │
│  • 非 JSON 或业务成功    │──► 返回 response
│  • 业务失败              │
│    → onBackendFail      │
│    → onError → reject   │
└────────────┬────────────┘

┌─────────────────────────┐
│ createRequest:           │
│   JSON → transform(res) │
│   其他 → response.data   │
├─────────────────────────┤
│ createFlatRequest:       │
│   成功 → { data, error: null }  │
│   失败 → { data: null, error }  │
└─────────────────────────┘

推荐用法

推荐使用 createRequest(抛异常风格),搭配 TanStack Query 使用效果最佳:

  • createRequest 在失败时抛出异常,天然契合 TanStack Query 的错误捕获机制
  • TanStack Query 负责缓存、去重、自动重试、后台刷新、loading/error 状态管理
  • createRequest 专注于请求发送、业务校验、数据转换
// 1. 定义请求函数 —— 只关心「发请求 + 拿数据」
export function fetchUserList(params: Api.UserListParams) {
  return request<Api.UserList>({
    url: '/api/users',
    params,
  });
}

// 2. 封装 Query Hook —— TanStack Query 接管状态
export function useUserListQuery(params: Api.UserListParams) {
  return useQuery({
    queryKey: ['users', params],
    queryFn: () => fetchUserList(params),
  });
}

// 3. 封装 Mutation Hook —— 写操作同理
export function useCreateUserMutation() {
  return useMutation({
    mutationFn: (data: Api.CreateUserParams) =>
      request<Api.User>({ url: '/api/users', method: 'post', data }),
  });
}

// 4. 在组件中使用
const UserList = () => {
  const { data, isLoading, error } = useUserListQuery({ page: 1 });
  const { mutate: createUser, isPending } = useCreateUserMutation();
  // ...
};

createFlatRequest 适合不使用 TanStack Query、需要手动控制错误流程的场景。

API

createRequest

创建一个抛异常风格的请求实例。业务失败或 HTTP 错误会抛出 AxiosError

function createRequest<ResponseData, ApiData, State>(
  axiosConfig?: CreateAxiosDefaults,
  options?: Partial<RequestOption<ResponseData, ApiData, State>>
): RequestInstance<ApiData, State>

类型参数:

参数说明示例
ResponseData后端原始响应体类型{ code: number; data: any; msg: string }
ApiDatatransform 转换后的业务数据类型any
State挂载在实例上的自定义状态类型Record<string, unknown>

示例:

interface BackendResponse<T = any> {
  code: number;
  data: T;
  msg: string;
}

const request = createRequest<BackendResponse>(
  { baseURL: 'https://api.example.com' },
  {
    isBackendSuccess: (response) => response.data.code === 200,
    transform: (response) => response.data.data,
    onRequest: async (config) => {
      config.headers.set('Authorization', `Bearer ${getToken()}`);
      return config;
    },
    onError: (error) => console.error(error.message),
  }
);

const userInfo = await request<Api.UserInfo>({ url: '/api/user' });

createFlatRequest

创建一个 Result 风格的请求实例,永远不抛异常。

function createFlatRequest<ResponseData, ApiData, State>(
  axiosConfig?: CreateAxiosDefaults,
  options?: Partial<RequestOption<ResponseData, ApiData, State>>
): FlatRequestInstance<ResponseData, ApiData, State>

返回值:

// 成功
{ data: ApiData; error: null; response: AxiosResponse }
// 失败
{ data: null; error: AxiosError; response: AxiosResponse }

示例:

const flatRequest = createFlatRequest<BackendResponse, BackendResponse['data']>(
  { baseURL: 'https://api.example.com' },
  {
    isBackendSuccess: (response) => response.data.code === 200,
    transform: (response) => response.data.data,
  }
);

const { data, error } = await flatRequest({ url: '/api/users' });
if (error) {
  console.error(error.message);
  return;
}
console.log(data);

配置项

Axios 默认配置

通过第一个参数传入,会与以下默认值合并:

配置默认值
headers.Content-Typeapplication/json
timeout10000(10 秒)
paramsSerializerqs.stringify
validateStatus200-299304

axios-retry 的配置也通过此对象传入,默认 retries: 0(不重试)。

RequestOption 钩子

钩子说明
isBackendSuccessHTTP 成功后判断业务是否成功(仅 JSON)
transform将原始响应转换为业务数据(仅 JSON 且业务成功)
onRequest请求前修改配置(注入 Token 等)
onBackendFail业务失败处理,可返回新响应实现重试
onError所有错误的统一回调
defaultStatecreateFlatRequest:初始化实例 state

错误处理

场景createRequestcreateFlatRequest
HTTP 错误 (4xx/5xx)onError → 抛出异常{ data: null, error }
业务错误onBackendFailonError → 抛出异常{ data: null, error }
请求取消onErrorERR_CANCELED)→ 抛出{ data: null, error }

通过 BACKEND_ERROR_CODE 区分业务错误与 HTTP 错误:

import { BACKEND_ERROR_CODE } from '@skyroc/axios';

if (error.code === BACKEND_ERROR_CODE) {
  // 业务错误:HTTP 成功但 code 不正确
} else {
  // HTTP 错误或网络错误
}

Token 刷新重试

通过 onBackendFail 实现:

createRequest<BackendResponse>(axiosConfig, {
  async onBackendFail(response, instance) {
    if (String(response.data.code) === '401') {
      const success = await refreshToken();
      if (success) {
        response.config.headers.Authorization = `Bearer ${getNewToken()}`;
        return instance.request(response.config);
      }
    }
    return null;
  },
});

请求取消

// cancelAllRequest 取消所有由包管理的请求
request.cancelAllRequest();

// 自定义 signal 的请求不受 cancelAllRequest 影响
const controller = new AbortController();
request({ url: '/api/data', signal: controller.signal });
request.cancelAllRequest(); // 不会取消上面的请求
controller.abort();         // 手动取消

响应类型

TypeScript 自动推导返回值类型:

const data = await request<Api.User>({ url: '/user' });            // → Api.User
const blob = await request({ url: '/file', responseType: 'blob' }); // → Blob
const text = await request({ url: '/text', responseType: 'text' }); // → string

非 JSON 响应不经过 transform,直接返回 response.data

实例状态

请求实例的 state 属性用于在请求生命周期中共享状态:

const request = createFlatRequest<BackendResponse, any, { token: string }>(
  axiosConfig,
  { defaultState: { token: '' } }
);

request.state.token = 'new-token';

与 @skyroc/service

在实际项目中,通常不直接使用 @skyroc/axios,而是通过 @skyroc/service 进行上层封装。它基于本包提供了平台适配器模式业务状态码管理Token 自动刷新错误消息去重等开箱即用的能力。详见 @skyroc/service 文档

常量与类型导出

常量:

常量说明
BACKEND_ERROR_CODE'BACKEND_ERROR'业务失败的 AxiosError code
REQUEST_ID_KEY'X-Request-Id'请求 ID header key

类型:

类型说明
RequestOption请求选项
RequestInstancecreateRequest 返回类型
FlatRequestInstancecreateFlatRequest 返回类型
FlatResponseDataFlat 请求的联合返回类型
CustomAxiosRequestConfig请求配置(支持 responseType 推导)
MappedType响应类型映射
ResponseType响应类型字面量
ContentTypeContent-Type 字面量

On this page