
resilience-engineering
by toilahuongg
SKILL.md
name: resilience-engineering description: Strategies for handling Shopify API Rate Limits (429), retry policies, and circuit breakers. Essential for high-traffic apps.
Resilience Engineering for Shopify Apps
Shopify's API limit is a "Leaky Bucket". If you pour too much too fast, it overflows (429 Too Many Requests). Your app must handle this gracefully.
1. Handling Rate Limits (429)
The "Retry-After" Header
When Shopify returns a 429, they include a Retry-After header (seconds to wait).
Implementation (using bottleneck or custom delay):
async function fetchWithRetry(url, options, retries = 3) {
try {
const res = await fetch(url, options);
if (res.status === 429) {
const wait = parseFloat(res.headers.get("Retry-After") || "1.0");
if (retries > 0) {
await new Promise(r => setTimeout(r, wait * 1000));
return fetchWithRetry(url, options, retries - 1);
}
}
return res;
} catch (err) {
// network error handling
}
}
Note: The official @shopify/shopify-api client handles retries automatically if configured.
2. Queues & Throttling
For bulk operations (e.g., syncing 10,000 products), you cannot just loop and await.
Using bottleneck
npm install bottleneck
import Bottleneck from "bottleneck";
const limiter = new Bottleneck({
minTime: 500, // wait 500ms between requests (2 req/sec)
maxConcurrent: 5,
});
const products = await limiter.schedule(() => shopify.rest.Product.list({ ... }));
Background Jobs (BullMQ)
Move heavy lifting to a background worker. (See redis-bullmq skill - to be added if needed, but conceptually here).
3. Circuit Breaker
If an external service (e.g., your own backend API or a shipping carrier) goes down, stop calling it to prevent cascading failures.
Using cockatiel
npm install cockatiel
import { CircuitBreaker, handleAll, retry } from 'cockatiel';
// Create a Retry Policy
const retryPolicy = retry(handleAll, { maxAttempts: 3, backoff: new ExponentialBackoff() });
// Create a Circuit Breaker (open after 5 failures, reset after 10s)
const circuitBreaker = new CircuitBreaker(handleAll, {
halfOpenAfter: 10 * 1000,
breaker: new ConsecutiveBreaker(5),
});
// Execute
const result = await retryPolicy.execute(() =>
circuitBreaker.execute(() => fetchMyService())
);
4. Webhook Idempotency
Shopify guarantees "at least once" delivery. You might receive the same orders/create webhook twice.
Fix: Store X-Shopify-Webhook-Id in Redis/DB with a short TTL (e.g., 24h). If it exists, ignore the request.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon