[ PROMPT_NODE_23992 ]
Bindings 设计模式
[ SKILL_DOCUMENTATION ]
# 绑定模式与最佳实践
## 服务绑定模式
### 通过服务绑定进行 RPC
typescript
// auth-worker
export default {
async fetch(request: Request, env: Env) {
const token = request.headers.get('Authorization');
return new Response(JSON.stringify({ valid: await validateToken(token) }));
}
}
// api-worker
const response = await env.AUTH_SERVICE.fetch(
new Request('https://fake-host/validate', {
headers: { 'Authorization': token }
})
);
**为什么使用 RPC?** 零延迟(同一数据中心),无 DNS,免费,类型安全。
**HTTP vs Service:**
typescript
// ❌ HTTP (慢,收费,跨区域延迟)
await fetch('https://auth-worker.example.com/validate');
// ✅ Service binding (快,免费,同一隔离环境)
await env.AUTH_SERVICE.fetch(new Request('https://fake-host/validate'));
**URL 不重要:** 服务绑定忽略主机名/协议,路由通过绑定名称进行。
### 类型化服务 RPC
typescript
// shared-types.ts
export interface AuthRequest { token: string; }
export interface AuthResponse { valid: boolean; userId?: string; }
// auth-worker
export default {
async fetch(request: Request): Promise {
const body: AuthRequest = await request.json();
const response: AuthResponse = { valid: true, userId: '123' };
return Response.json(response);
}
}
// api-worker
const response = await env.AUTH_SERVICE.fetch(
new Request('https://fake/validate', {
method: 'POST',
body: JSON.stringify({ token } satisfies AuthRequest)
})
);
const data: AuthResponse = await response.json();
## Secrets 管理
bash
# 设置 secret
npx wrangler secret put API_KEY
cat api-key.txt | npx wrangler secret put API_KEY
npx wrangler secret put API_KEY --env staging
typescript
// 使用 secret
const response = await fetch('https://api.example.com', {
headers: { 'Authorization': `Bearer ${env.API_KEY}` }
});
**永远不要提交 Secrets:**
c
// ❌ 绝对禁止
{ "vars": { "API_KEY": "sk_live_abc123" } }
## 使用 Mock 绑定进行测试
### Vitest Mock
typescript
import { vi } from 'vitest';
const mockKV: KVNamespace = {
get: vi.fn(async (key) => key === 'test' ? 'value' : null),
put: vi.fn(async () => {}),
delete: vi.fn(async () => {}),
list: vi.fn(async () => ({ keys: [], list_complete: true, cursor: '' })),
getWithMetadata: vi.fn(),
} as unknown as KVNamespace;
const mockEnv: Env = { MY_KV: mockKV };
const mockCtx: ExecutionContext = {
waitUntil: vi.fn(),
passTh