API: Rate limit exceeded
外部APIのレート制限に達した際のエラー原因と解決策
概要
外部APIの呼び出し回数制限に達した際に発生するエラーです。
エラーメッセージ
``` HTTP 429 Too Many Requests { “error”: “rate_limit_exceeded”, “message”: “Rate limit exceeded. Please retry after 60 seconds.”, “retry_after”: 60 } ```
原因
- 短時間に大量リクエスト: バースト的なAPI呼び出し
- 並列処理の過多: 同時リクエスト数超過
- キャッシュ未使用: 同じデータを繰り返し取得
- リトライの嵐: エラー時の無制限リトライ
解決策
1. Exponential Backoffを実装
```javascript async function fetchWithRetry(url, options = {}, maxRetries = 5) { for (let i = 0; i < maxRetries; i++) { const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
console.log(\`Rate limited. Retrying after \${retryAfter}s\`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}
return response;
} throw new Error(‘Max retries exceeded’); } ```
2. キャッシュを活用
```javascript const cache = new Map(); const CACHE_TTL = 60000; // 1分
async function fetchWithCache(url) { const cached = cache.get(url); if (cached && Date.now() - cached.time < CACHE_TTL) { return cached.data; }
const response = await fetch(url); const data = await response.json(); cache.set(url, { data, time: Date.now() }); return data; } ```
3. リクエストをキューイング
```javascript class RateLimiter { constructor(maxRequests, interval) { this.maxRequests = maxRequests; this.interval = interval; this.queue = []; this.running = 0; }
async add(fn) { return new Promise((resolve, reject) => { this.queue.push({ fn, resolve, reject }); this.process(); }); }
async process() { if (this.running >= this.maxRequests || this.queue.length === 0) return;
this.running++;
const { fn, resolve, reject } = this.queue.shift();
try {
resolve(await fn());
} catch (e) {
reject(e);
} finally {
setTimeout(() => {
this.running--;
this.process();
}, this.interval / this.maxRequests);
}
} }
// 使用例: 10リクエスト/秒 const limiter = new RateLimiter(10, 1000); await limiter.add(() => fetch(’/api/data’)); ```
4. バルクAPIを使用
```javascript // 悪い例: 1件ずつ for (const id of ids) { await fetch(`/api/users/${id}`); }
// 良い例: バルクで取得 await fetch(’/api/users’, { method: ‘POST’, body: JSON.stringify({ ids }) }); ```
よくある間違い
- リトライ間隔を固定値にする
- Retry-Afterヘッダーを無視
- 全スレッドが同時にリトライ
関連エラー
関連エラー
API の他のエラー
この記事は役に立ちましたか?