apollo-local-dev-loop
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseApollo Local Dev Loop
Apollo 本地开发循环
Overview
概述
Set up efficient local development workflow for Apollo.io integrations with proper environment management, testing, and debugging.
为Apollo.io集成搭建高效的本地开发工作流,包含完善的环境管理、测试与调试方案。
Prerequisites
前提条件
- Completed setup
apollo-install-auth - Node.js 18+ or Python 3.10+
- Git repository initialized
- 已完成配置
apollo-install-auth - Node.js 18+ 或 Python 3.10+
- 已初始化Git仓库
Instructions
操作步骤
Step 1: Environment Setup
步骤1:环境配置
bash
undefinedbash
undefinedCreate environment files
创建环境文件
touch .env .env.example .env.test
touch .env .env.example .env.test
Add to .gitignore
添加到.gitignore
echo '.env' >> .gitignore
echo '.env.local' >> .gitignore
```bashecho '.env' >> .gitignore
echo '.env.local' >> .gitignore
```bash.env.example (commit this)
.env.example(需提交到仓库)
APOLLO_API_KEY=your-api-key-here
APOLLO_RATE_LIMIT=100
APOLLO_ENV=development
undefinedAPOLLO_API_KEY=your-api-key-here
APOLLO_RATE_LIMIT=100
APOLLO_ENV=development
undefinedStep 2: Create Development Client
步骤2:创建开发客户端
typescript
// src/lib/apollo-dev.ts
import axios from 'axios';
const isDev = process.env.NODE_ENV !== 'production';
export const apolloClient = axios.create({
baseURL: 'https://api.apollo.io/v1',
params: { api_key: process.env.APOLLO_API_KEY },
});
// Add request logging in development
if (isDev) {
apolloClient.interceptors.request.use((config) => {
console.log(`[Apollo] ${config.method?.toUpperCase()} ${config.url}`);
return config;
});
apolloClient.interceptors.response.use(
(response) => {
console.log(`[Apollo] Response: ${response.status}`);
return response;
},
(error) => {
console.error(`[Apollo] Error: ${error.response?.status}`, error.message);
return Promise.reject(error);
}
);
}typescript
// src/lib/apollo-dev.ts
import axios from 'axios';
const isDev = process.env.NODE_ENV !== 'production';
export const apolloClient = axios.create({
baseURL: 'https://api.apollo.io/v1',
params: { api_key: process.env.APOLLO_API_KEY },
});
// 在开发环境中添加请求日志
if (isDev) {
apolloClient.interceptors.request.use((config) => {
console.log(`[Apollo] ${config.method?.toUpperCase()} ${config.url}`);
return config;
});
apolloClient.interceptors.response.use(
(response) => {
console.log(`[Apollo] 响应状态: ${response.status}`);
return response;
},
(error) => {
console.error(`[Apollo] 错误: ${error.response?.status}`, error.message);
return Promise.reject(error);
}
);
}Step 3: Create Mock Server for Testing
步骤3:创建测试用Mock服务器
typescript
// src/mocks/apollo-mock.ts
import { rest } from 'msw';
export const apolloHandlers = [
rest.post('https://api.apollo.io/v1/people/search', (req, res, ctx) => {
return res(
ctx.json({
people: [
{ id: '1', name: 'Test User', title: 'Engineer', email: 'test@example.com' },
],
pagination: { page: 1, per_page: 10, total_entries: 1 },
})
);
}),
rest.get('https://api.apollo.io/v1/organizations/enrich', (req, res, ctx) => {
return res(
ctx.json({
organization: {
name: 'Test Company',
domain: 'test.com',
industry: 'Technology',
},
})
);
}),
];typescript
// src/mocks/apollo-mock.ts
import { rest } from 'msw';
export const apolloHandlers = [
rest.post('https://api.apollo.io/v1/people/search', (req, res, ctx) => {
return res(
ctx.json({
people: [
{ id: '1', name: 'Test User', title: 'Engineer', email: 'test@example.com' },
],
pagination: { page: 1, per_page: 10, total_entries: 1 },
})
);
}),
rest.get('https://api.apollo.io/v1/organizations/enrich', (req, res, ctx) => {
return res(
ctx.json({
organization: {
name: 'Test Company',
domain: 'test.com',
industry: 'Technology',
},
})
);
}),
];Step 4: Development Scripts
步骤4:开发脚本配置
json
{
"scripts": {
"dev": "NODE_ENV=development tsx watch src/index.ts",
"dev:mock": "MOCK_APOLLO=true npm run dev",
"test:apollo": "vitest run src/**/*.apollo.test.ts",
"apollo:quota": "tsx scripts/check-apollo-quota.ts"
}
}json
{
"scripts": {
"dev": "NODE_ENV=development tsx watch src/index.ts",
"dev:mock": "MOCK_APOLLO=true npm run dev",
"test:apollo": "vitest run src/**/*.apollo.test.ts",
"apollo:quota": "tsx scripts/check-apollo-quota.ts"
}
}Step 5: Quota Monitoring Script
步骤5:配额监控脚本
typescript
// scripts/check-apollo-quota.ts
import { apolloClient } from '../src/lib/apollo-dev';
async function checkQuota() {
try {
const { data } = await apolloClient.get('/auth/health');
console.log('API Status:', data);
// Note: Apollo doesn't expose quota directly, track usage manually
} catch (error: any) {
if (error.response?.status === 429) {
console.error('Rate limited! Wait before making more requests.');
}
}
}
checkQuota();typescript
// scripts/check-apollo-quota.ts
import { apolloClient } from '../src/lib/apollo-dev';
async function checkQuota() {
try {
const { data } = await apolloClient.get('/auth/health');
console.log('API状态:', data);
// 注意:Apollo不直接暴露配额信息,需手动跟踪使用情况
} catch (error: any) {
if (error.response?.status === 429) {
console.error('触发速率限制!请等待后再发起请求。');
}
}
}
checkQuota();Output
输出结果
- Environment file structure (.env, .env.example)
- Development client with logging interceptors
- Mock server for testing without API calls
- npm scripts for development workflow
- Quota monitoring utility
- 环境文件结构(.env、.env.example)
- 带有日志拦截器的开发客户端
- 无需调用真实API的Mock测试服务器
- 用于开发工作流的npm脚本
- 配额监控工具
Error Handling
错误处理
| Error | Cause | Solution |
|---|---|---|
| Missing API Key | .env not loaded | Run |
| Mock Not Working | MSW not configured | Ensure setupServer is called |
| Rate Limited in Dev | Too many test calls | Use mock server for tests |
| Stale Credentials | Key rotated | Update .env with new key |
| 错误 | 原因 | 解决方案 |
|---|---|---|
| API密钥缺失 | .env文件未加载 | 执行 |
| Mock功能失效 | MSW未配置 | 确保已调用setupServer |
| 开发环境触发速率限制 | 测试请求过多 | 使用Mock服务器进行测试 |
| 凭证过期 | 密钥已轮换 | 更新.env文件中的密钥 |
Examples
示例
Watch Mode Development
监听模式开发
bash
undefinedbash
undefinedTerminal 1: Run dev server with watch
终端1:启动带监听的开发服务器
npm run dev
npm run dev
Terminal 2: Test API calls
终端2:测试API调用
curl -X POST http://localhost:3000/api/apollo/search
-H "Content-Type: application/json"
-d '{"domain": "stripe.com"}'
-H "Content-Type: application/json"
-d '{"domain": "stripe.com"}'
undefinedcurl -X POST http://localhost:3000/api/apollo/search
-H "Content-Type: application/json"
-d '{"domain": "stripe.com"}'
-H "Content-Type: application/json"
-d '{"domain": "stripe.com"}'
undefinedTesting with Mocks
使用Mock进行测试
typescript
// src/services/apollo.apollo.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { setupServer } from 'msw/node';
import { apolloHandlers } from '../mocks/apollo-mock';
import { searchPeople } from './apollo';
const server = setupServer(...apolloHandlers);
beforeAll(() => server.listen());
afterAll(() => server.close());
describe('Apollo Service', () => {
it('searches for people', async () => {
const results = await searchPeople({ domain: 'test.com' });
expect(results.people).toHaveLength(1);
expect(results.people[0].name).toBe('Test User');
});
});typescript
// src/services/apollo.apollo.test.ts
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { setupServer } from 'msw/node';
import { apolloHandlers } from '../mocks/apollo-mock';
import { searchPeople } from './apollo';
const server = setupServer(...apolloHandlers);
beforeAll(() => server.listen());
afterAll(() => server.close());
describe('Apollo 服务', () => {
it('搜索人员信息', async () => {
const results = await searchPeople({ domain: 'test.com' });
expect(results.people).toHaveLength(1);
expect(results.people[0].name).toBe('Test User');
});
});Resources
参考资源
Next Steps
下一步
Proceed to for production-ready code patterns.
apollo-sdk-patterns继续学习以获取生产环境就绪的代码模式。
apollo-sdk-patterns