@vxil / sdk
的类型化JavaScript/TypeScript客户端 Vxil REST API -后端构建块(auth, cms,文件,支付集成,通知,作业,实时,矢量搜索,AI等)在一行中启用。
npm install @vxil/sdk
import { Vxil } from '@vxil/sdk';
const vx = new Vxil({ apiKey: process.env.VXIL_API_KEY! });
await vx.users.upsert({ id: 'u_1', email: '[email protected]' });
await vx.notifications.send({ user_id: 'u_1', template: 'welcome', data: { app_name: 'MyApp' } });
const { items } = await vx.from('tasks').query({ filter: { status: 'open' } });
- 零依赖关系。运行在任何地方
fetch存在:节点≥22,浏览器,边缘运行时间,和 React Native / Expo (Hermes) - SDK不使用任何WHATWGURL/URLSearchParamssurface React Native只提供了部分功能。 - 默认为
https://api.vxil.com;通过baseUrl瞄准另一个环境。 - 租户启用的每个特性都可以作为类型化命名空间使用;生成与项目精确相关的客户端
npx @vxil/cli gen. - 每个非2xx响应都会抛出一个
VxilError携带结构化错误信封(status,code,message,hint,fixUrl,requestId,retryAfter服务器发送时的秒数Retry-After)。
服务器模式和最终用户模式
一、 服务器密钥 是一个秘密:把它放在服务器路由处理程序中,永远不要把它放在浏览器或应用包中。要从浏览器或电话中直接调用Vxil,请使用 瘦客户机关键 ( end_user_required 类-它拒绝任何没有有效的终端用户会话的请求)以及登录用户的会话令牌:
const vx = new Vxil({
apiKey: PUBLIC_VXIL_KEY, // thin-client key: reads + owner-scoped writes only
endUserToken: session.token, // from vx.auth.signIn / your sign-in flow
});
// reads and writes on owner-scoped resources are confined to this user
const { items } = await vx.from('meals').query({ limit: 20 });
vx.asEndUser(token) 返回另一个会话的客户端,并继承其他所有内容;SDK中没有任何东西缓存令牌。
重试、超时和请求挂钩
这三个都是 默认关闭 -如果没有设置,客户端是单一的 fetch 每个电话,和以前一样。
const vx = new Vxil({
apiKey,
timeoutMs: 10_000, // per attempt; aborts the request AND its body read
retry: { attempts: 2 }, // up to 3 requests in total
hooks: {
beforeRequest: (req) => ({ 'x-request-id': crypto.randomUUID() }),
afterResponse: ({ request, response, durationMs }) => log(request.method, request.url, response.status, durationMs),
onRetry: ({ request, delayMs, status, error }) => log('retry', request.url, delayMs, status ?? error),
},
});
| 选项 | 默认的 | 意义 |
|---|---|---|
retry.attempts | 0 (关闭) | 第一次尝试后重试。 |
retry.retryOn | [429, 502, 503, 504] | 触发重试的响应状态。 |
retry.backoffMs | 250 | 首先延迟;每次重试双倍,有抖动 [½, 1] 计算出的延迟。 |
retry.maxBackoffMs | 10_000 | 两次尝试之间的最长等待时间。一个 Retry-After 超过它结束循环,而不是等待。 |
retry.respectRetryAfter | true | 使用响应的 Retry-After (秒或HTTP-date)作为存在时的延迟。 |
retry.retryOnNetworkError | true | 在以下情况下重试 fetch 本身失败(DNS,重置,a timeoutMs 超时)。 |
timeoutMs | 无 | 每次尝试超时 AbortController; 抛出 VxilError { status: 0, code: 'request_timeout' }. |
hooks.beforeRequest | - - - - - - | 在每一次尝试之前奔跑;可能为该尝试返回要添加的标头。 |
hooks.afterResponse | - - - - - - | 在每个响应(重试或最终)之后运行,包含响应及其持续时间。 |
hooks.onRetry | - - - - - - | 在客户端休眠以进行重试之前运行。 |
确保重试安全的规则:
- 只有幂等请求才会被重试:
GET,HEAD,PUT,DELETE,和POST只有当调用带有Idempotency-Key({ idempotencyKey }选择金钱路线-payments.credits.consume,notifications.send,……)。一个光秃秃的POST或者一个PATCH永远不会重试retry说。 - 钩子接收 冻 请求描述符(
method,url,headers,attempt),它从不包含凭证头,并且它们也不能设置它们;用vx.asEndUser(token). - 抛出钩子中止调用。钩子看到的响应体已经被读取;检查
status和headers.
错误
import { VxilError } from '@vxil/sdk';
try {
await vx.payments.credits.consume({ user_id, credit_type: 'tokens', amount: 5 }, { idempotencyKey });
} catch (e) {
if (e instanceof VxilError && e.status === 429) {
showToast(`Try again in ${Math.ceil(e.retryAfter ?? 30)}s`);
}
}
更新日志
0.4.1 - 2026-09-13
- 仅支持文档:JSDoc不再引用内部存储库路径;转而指向公共导游。没有运行时更改。
0.4.0 - 2026-09-11
- React-Native-clean:每个查询字符串构建时都没有
URLSearchParams(React Native的polyfill启动.set之前0.81);连线字节不变。 VxilError.retryAfter(秒)解析自Retry-After.- 可选
retry,timeoutMs和hooks客户端的选项(见上文)。没有行为改变,除非设置。
0.3.0
- 代理内环波:结构化输出,使用,
@vxil/react同伴。
文档: vxil.com/docs/guide ·仪表板: vxil.com/dashboard ·条件: vxil.com/terms
MIT©techmaker.io