Utiliser Retry
/rate-limits-paginationBigCommerce applique des limites de débit. Maîtrisez pagination, traitement par lots et stratégies de retry pour créer des intégrations robustes.
<overview>
BigCommerce enforces rate limits to ensure platform reliability. Understanding these limits and implementing proper pagination, batching, and retry strategies is essential for robust integrations.
</overview>
<rate_limits>
<standard_limits>
| API Type | Limit |
|---|---|
| REST API (Standard) | 20,000 requests/hour |
| Payments API | 50 requests/4 seconds |
| B2B Edition | 150 requests/minute |
| GraphQL Storefront | Query complexity limits |
</standard_limits>
<b2bendpointlimits>
Some B2B Edition endpoints have specific limits:
- Add Company Attachment: 15 requests/minute
- Check endpoint documentation for specific quotas
</b2bendpointlimits>
<ratelimitheaders>
Monitor these response headers:
X-Rate-Limit-Requests-Left: 19850 # Remaining requests
X-Rate-Limit-Time-Reset-Ms: 3600000 # Time until reset (ms)
X-Retry-After: 300 # Seconds to wait (when limited)</ratelimitheaders>
<429_response>
When rate limited, you receive HTTP 429:
{
"status": 429,
"title": "Too Many Requests",
"type": "https://developer.bigcommerce.com/docs/start/about/status-codes",
"detail": "Rate limit exceeded"
}</429_response>
</rate_limits>
<retry_strategy>
<exponential_backoff>
import time
import random
def make_request_with_retry(func, max_retries=10):
base_delay = 1 # seconds
for attempt in range(max_retries):
try:
response = func()
if response.status_code == 429:
# Use Retry-After header if present
retry_after = response.headers.get('X-Retry-After', None)
if retry_after:
time.sleep(int(retry_after))
else:
# Exponential backoff with jitter
delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
time.sleep(min(delay, 300)) # Cap at 5 minutes
continue
return response
except Exception as e:
if attempt == max_retries - 1:
raise
delay = base_delay * (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
raise Exception("Max retries exceeded")</exponential_backoff>
<jitter>
Add random jitter to prevent thundering herd:
# Without jitter: all retries happen at exactly 2s, 4s, 8s...
# With jitter: retries spread out across time window
delay = base_delay * (2 ** attempt)
jitter = random.uniform(0, delay * 0.1) # 10% jitter
total_delay = delay + jitter</jitter>
</retry_strategy>
<pagination>
<cursorvsoffset>
Cursor pagination (recommended):
- More efficient for large datasets
- Consistent results during iteration
- Lower computational complexity
- Used by GraphQL and some REST endpoints
Offset pagination:
- Simpler to implement
- Allows jumping to specific pages
- Less efficient for large datasets
- Data can shift between requests
</cursorvsoffset>
<rest_pagination>
REST APIs use offset pagination via page and limit:
# First page
GET /v3/catalog/products?page=1&limit=100
# Response includes meta object
{
"data": [...],
"meta": {
"pagination": {
"total": 500,
"count": 100,
"per_page": 100,
"current_page": 1,
"total_pages": 5,
"links": {
"current": "?page=1&limit=100",
"next": "?page=2&limit=100"
}
}
}
}
# Next page
GET /v3/catalog/products?page=2&limit=100Max limit: 250 items per page for most endpoints
</rest_pagination>
<graphqlcursorpagination>
GraphQL uses cursor-based pagination:
query GetProducts($first: Int!, $after: String) {
site {
products(first: $first, after: $after) {
edges {
node {
entityId
name
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
}
}
}Pagination loop:
async function getAllProducts() {
let allProducts = [];
let hasNextPage = true;
let cursor = null;
while (hasNextPage) {
const response = await graphqlRequest({
query: GET_PRODUCTS,
variables: { first: 50, after: cursor }
});
const { edges, pageInfo } = response.data.site.products;
allProducts = allProducts.concat(edges.map(e => e.node));
hasNextPage = pageInfo.hasNextPage;
cursor = pageInfo.endCursor;
}
return allProducts;
}</graphqlcursorpagination>
</pagination>
<batching>
<product_batching>
Update multiple products in one request (max 10):
PUT /v3/catalog/products
[
{"id": 111, "price": 29.99},
{"id": 112, "price": 39.99},
{"id": 113, "price": 49.99}
]Savings: 10 products = 1 request instead of 10
</product_batching>
<customer_batching>
Create/update multiple customers:
POST /v3/customers
[
{"email": "user1@example.com", "first_name": "User", "last_name": "One"},
{"email": "user2@example.com", "first_name": "User", "l