@h-ai/api-client
v0.1.0-alpha.33
Published
Hai Framework universal HTTP client with Bearer token and API contract support.
Readme
@h-ai/api-client
hai-framework 的跨端 oRPC/OpenAPI typed client,面向 Web、App、小程序等运行时提供统一 API 调用与 Token 管理。
能力概览
apiClient:默认绑定 iam/storage/ai 领域的统一 typed client 入口。apiClient.create(contract):为自定义 contract 创建 typed client。apiClient.tokenStorage.{memory,localStorage,httpOnlyCookie}():Token 存储工厂。- 支持自定义
fetch,适配浏览器、Node、Capacitor、小程序桥接层。 - 支持 Bearer Token 自动注入、401 后刷新并重试一次。
- 网络错误统一转换为
HaiResult错误。 - 可选传输加密:
apiClient.init({ transport: { crypto } })自动使用crypto.transport.createClient()。 - 传输加密与自动刷新可同时启用:401 后的
/auth/refresh会继续走 encrypted fetch,不降级明文。
快速开始
import { apiClient } from '@h-ai/api-client'
await apiClient.init({
baseUrl: 'https://api.example.com/api/v1',
auth: {}, // 默认使用 httpOnly cookie 存储(推荐);SSR 测试请显式传入 apiClient.tokenStorage.memory()
})
const login = await apiClient.iam.auth.login({
identifier: 'alice',
password: 'secret',
})
if (login.success) {
// httpOnly cookie 模式下 refresh token 由服务端 Set-Cookie 管理,
// api-client 默认存储只需要把 access token 写入内存。
await apiClient.auth.setTokens(login.data.tokens)
}
const me = await apiClient.iam.auth.currentUser()
await apiClient.close()启用传输加密
服务端需先启用 serv.createApp({ transport: { crypto } });客户端只注入同一个 @h-ai/crypto 服务实例,无需手写密钥协商代码。
import { apiClient } from '@h-ai/api-client'
import { crypto } from '@h-ai/crypto'
await crypto.init()
await apiClient.init({
baseUrl: 'https://api.example.com/api/v1',
auth: {},
transport: { crypto }, // 默认协商路径:/api/v1/_hai/key-exchange
})
await apiClient.close()
await crypto.close()API 契约
自定义应用可以绑定自己的 oRPC contract:
import { apiClient } from '@h-ai/api-client'
import { apiContract } from '@h-ai/api-contract'
const contract = apiContract.create({ iam: apiContract.iam })
const client = apiClient.create(contract)
await client.init({ baseUrl: 'https://api.example.com/api/v1' })
const result = await client.iam.auth.login({ identifier: 'alice', password: 'secret' })API 概览
apiClient.init(config):初始化默认 client。apiClient.close():清理 client 状态。apiClient.auth.setTokens(tokens):写入 access token;非 httpOnly 存储会同时写入 refresh token。apiClient.auth.clear():清理 token。apiClient.create(contract):创建自定义 typed client。
已初始化后再次调用 init() 会返回 CONFIG_ERROR,不会覆盖现有 client;如需切换 baseUrl / fetch / transport,请先 await apiClient.close() 再重新初始化。
配置
baseUrl:API 基础地址,通常包含/api/v1。auth.storage:Token 存储适配器;默认apiClient.tokenStorage.httpOnlyCookie()(浏览器推荐);SSR / 测试场景请显式传入apiClient.tokenStorage.memory()。auth.refreshPath:刷新 token 路径,默认/auth/refresh。timeout:请求超时,默认 30000ms。headers:静态或动态公共请求头。fetch:自定义 fetch 实现。transport.crypto:启用透明请求/响应加解密,必须传入已初始化的@h-ai/crypto实例。transport.keyExchangePath:密钥协商子路径,默认/_hai/key-exchange;会自动拼接到baseUrl后。apiClient.config:返回脱敏后的运行配置快照;baseUrl的内嵌凭证、headers.authorization等敏感值会自动隐藏。
错误处理
业务 API 返回 HaiResult<T>:
const result = await apiClient.iam.auth.currentUser()
if (!result.success) {
// result.error.code / result.error.message
}未初始化、网络错误、超时、401/403/404 等客户端侧问题也会转换为失败的 HaiResult。
测试
pnpm --filter @h-ai/api-client test
pnpm --filter @h-ai/api-client typecheckLicense
Apache-2.0
