Skip to content
On this page

HTTP 基础设施

@grow-admin-rock/infrastructure 基于 Axios 封装 HTTP 请求,通过 IOC 注入 InfrastructureAxios 实例。宿主应用在 initIoc.ts 中绑定自定义 AxiosTransformInfrastructureOptions

架构

业务代码 / API 模块
        ↓ useRequest() 或 diKT(InfrastructureAxios)
InfrastructureAxios(拦截器链)
        ↓ AxiosTransform(宿主可扩展)
        ↓ checkStatus(401 等状态码处理)
后端 API

宿主扩展:GrowAxiosTransform

sample/src/apis/infrastructure.ts 演示如何继承 AxiosTransform

typescript
@Bean()
export class GrowAxiosTransform extends AxiosTransform {
  constructor(@Autowired(infrastructureLib.types.InfrastructureOptions) _options) {
    super()

    // 请求前:拼接 baseURL
    this.beforeRequestHook = (config, options) => {
      const { apiUrl } = options
      if (!config.baseURL && apiUrl) {
        config.baseURL = isString(apiUrl) ? apiUrl : ''
      }
      return config
    }

    // 响应后:统一解包 { data } / { result }
    this.transformRequestHook = (rawRes, options) => {
      const { data } = rawRes
      if (data.type === 'error') throw new Error(data.message || '请求失败')
      return data.data ?? data.result ?? data
    }
  }
}

initIoc.ts 中绑定:

typescript
appContext.iocModules.push(
  new AsyncIocModule(async (bind) => {
    bind(infrastructureLib.types.AxiosTransform).to(GrowAxiosTransform)
    bind(infrastructureLib.types.InfrastructureOptions).toDynamicValue(() => {
      const { apiUrl } = getGlobalConfig(import.meta.env)
      return { apiUrl }
    })
  }),
)

业务代码调用

typescript
import { useRequest } from '@/apis/infrastructure'

const request = useRequest()

// 示例:获取菜单列表(apps-home)
export function getMenuList() {
  return request.get({ url: '/api/menu/list' })
}

useRequest() 内部通过 diKT(infrastructureLib.types.InfrastructureAxios) 从 IOC 容器获取实例。

响应数据格式

GrowAxiosTransform 默认期望后端返回:

json
{
  "type": "success",
  "data": { ... },
  "message": "操作成功"
}

Mock 工具 resultSuccess / resultError@grow-admin-rock/mock/util)已按此格式封装,开发环境可直接对接。

字段说明
type: 'error'视为业务失败,抛出 message
data优先作为返回值
resultdata 不存在时的备选字段

请求选项

通过 RequestOptions@grow-admin-rock/types)控制单次请求行为:

选项说明
isReturnNativeResponse返回原始 Axios 响应
isTransformResponse是否走 transformRequestHook 解包
apiUrl覆盖 baseURL

环境如何区分(本地 / 测试 / 生产)

框架不是按接口配置多套 host,而是靠 Vite mode + 环境文件 决定整站统一的 API 前缀:

sample/.env.[mode]  →  VITE_GLOB_API_URL
        ↓ getGlobalConfig(import.meta.env).apiUrl
        ↓ IoC:InfrastructureOptions.apiUrl
        ↓ GrowAxiosTransform.beforeRequestHook → axios baseURL
业务只写相对路径,如 /user/info
环境典型命令读取文件关键变量
本地开发pnpm serve / vite.env + .env.developmentVITE_GLOB_API_URLVITE_PROXYVITE_USE_MOCK
生产构建vite build.env + .env.productionVITE_GLOB_API_URLVITE_USE_MOCK

当前 sample 默认两边都是 VITE_GLOB_API_URL=/mock(配合客户端 Mock)。对接真实后端时:

  • 开发:改为 /api(或其它代理前缀),并配置下方 VITE_PROXY
  • 生产:改为网关对外前缀(如 /api),由 Nginx / API 网关 反代,不依赖 Vite 代理

生产构建还会把 VITE_GLOB_* 抽成独立 _app.config.js,挂到 window.__PRODUCTION__GROW_ADMIN__CONF__

  • 开发getAppConfig 直接读 import.meta.env
  • 生产:读 window 上这份配置(部署后可改,不必重编)

测试 / 预发环境

仓库默认没有 .env.test / .env.staging。需要时可新增对应文件,并用 vite --mode test / vite build --mode staging 加载;区分方式仍是换整站 VITE_GLOB_API_URL,而不是按接口选 host。

开发环境多代理(VITE_PROXY)

多后端转发依赖宿主 env 文件中的 VITE_PROXY,由 @grow-admin-config/vite 解析后注入 Vite server.proxy(或 https 下的 http2-proxy 插件)。

配置项作用阶段说明
sample/.env.developmentVITE_PROXYvite 本地开发主要配置位置
sample/.env.productionVITE_PROXY生产构建基本无效;生产用网关 + VITE_GLOB_API_URL

格式

JSON 数组 [[前缀, 目标地址], ...]。解析时单引号会转成双引号;resolveProxyrewrite 去掉前缀

浏览器请求  /api/user/info
  → 代理到   http://127.0.0.1:8080/user/info

示例(写在 .env.development

env
# 关闭 Mock,走真实后端
VITE_USE_MOCK = false

# 与下方代理前缀对齐(业务 baseURL)
VITE_GLOB_API_URL = /api

# 多代理:主 API + 上传 + 认证
VITE_PROXY = [["/api","http://127.0.0.1:8080"],["/upload","http://127.0.0.1:9000"],["/auth","https://auth-test.example.com"]]

# 普通 http:上面 VITE_PROXY 已足够(server.proxy)
# 若开启 https,需同时打开下面两项,走 vite-plugin-http2-proxy
VITE_USE_HTTPS = false
VITE_USE_PROXY = false

解析链路

loadEnv(mode) → wrapperEnv(解析 VITE_PROXY JSON)
    → resolveProxy → vite server.proxy   (http,默认)
    → 或 VITE_USE_HTTPS + VITE_USE_PROXY → vite-plugin-http2-proxy

相关实现:configs/vite/src/utils/index.tswrapperEnv / resolveProxy)、configs/vite/src/index.tsserver.proxy)、configs/vite/src/plugins/https.ts

与 Mock 的关系

场景建议配置
纯本地 MockVITE_USE_MOCK=trueVITE_GLOB_API_URL=/mock,可不配 VITE_PROXY
代理真实后端VITE_USE_MOCK=falseVITE_GLOB_API_URL 与代理前缀一致,配置 VITE_PROXY
部分接口 Mock、部分走代理前缀分开(如 /mock vs /api),业务侧按需覆盖单次请求的 apiUrl / baseURL

生产不要依赖 VITE_PROXY

VITE_PROXY 只作用于本地 Vite 开发服。生产请在 Nginx / 网关配置反代;.env.production 中至多保留注释示例,避免误以为构建产物会启用 Vite 代理。

错误处理与取消

能力位置说明
HTTP 状态码rock-infrastructure/src/checkStatus.ts401 等触发 InfrastructureOptions.onUnauthorized
请求取消RequestCanceler路由切换时可取消 pending 请求
全局 pendingprojectSetting.removeAllHttpPending切换路由时移除所有未完成请求

下一步