cloudflare
references/api/patterns.md
.md 205 lines
Content
# Common Patterns
## List All with Auto-Pagination
**Problem:** API returns paginated results. Default page size is 20.
**Solution:** Use SDK auto-pagination to iterate all results.
```typescript
// TypeScript
for await (const zone of client.zones.list()) {
console.log(zone.name);
}
```
```python
# Python
for zone in client.zones.list():
print(zone.name)
```
```go
// Go
iter := client.Zones.ListAutoPaging(ctx, cloudflare.ZoneListParams{})
for iter.Next() {
fmt.Println(iter.Current().Name)
}
```
## Error Handling with Retry
**Problem:** Rate limits (429) and transient errors need retry.
**Solution:** SDKs auto-retry with exponential backoff. Customize as needed.
```typescript
// Increase retries for rate-limit-heavy operations
const client = new Cloudflare({ maxRetries: 5 });
try {
const zone = await client.zones.create({ /* ... */ });
} catch (err) {
if (err instanceof Cloudflare.RateLimitError) {
// Already retried 5 times with backoff
const retryAfter = err.headers['retry-after'];
console.log(`Rate limited. Retry after ${retryAfter}s`);
}
}
```
## Batch Parallel Operations
**Problem:** Need to create multiple resources quickly.
**Solution:** Use `Promise.all()` for parallel requests (respect rate limits).
```typescript
// Create multiple DNS records in parallel
const records = ['www', 'api', 'cdn'].map(subdomain =>
client.dns.records.create({
zone_id: 'zone-id',
type: 'A',
name: `${subdomain}.example.com`,
content: '192.0.2.1',
})
);
await Promise.all(records);
```
**Controlled concurrency** (avoid rate limits):
```typescript
import pLimit from 'p-limit';
const limit = pLimit(10); // Max 10 concurrent
const subdomains = ['www', 'api', 'cdn', /* many more */];
const records = subdomains.map(subdomain =>
limit(() => client.dns.records.create({
zone_id: 'zone-id',
type: 'A',
name: `${subdomain}.example.com`,
content: '192.0.2.1',
}))
);
await Promise.all(records);
```
## Zone CRUD Workflow
```typescript
// Create
const zone = await client.zones.create({
account: { id: 'account-id' },
name: 'example.com',
type: 'full',
});
// Read
const fetched = await client.zones.get({ zone_id: zone.id });
// Update
await client.zones.edit(zone.id, { paused: false });
// Delete
await client.zones.delete(zone.id);
```
## DNS Bulk Update
```typescript
// Fetch all A records
const records = [];
for await (const record of client.dns.records.list({
zone_id: 'zone-id',
type: 'A',
})) {
records.push(record);
}
// Update all to new IP
await Promise.all(records.map(record =>
client.dns.records.update({
zone_id: 'zone-id',
dns_record_id: record.id,
type: 'A',
name: record.name,
content: '203.0.113.1', // New IP
proxied: record.proxied,
ttl: record.ttl,
})
));
```
## Filter and Collect Results
```typescript
// Find all proxied A records
const proxiedRecords = [];
for await (const record of client.dns.records.list({
zone_id: 'zone-id',
type: 'A',
})) {
if (record.proxied) {
proxiedRecords.push(record);
}
}
```
## Error Recovery Pattern
```typescript
async function createZoneWithRetry(name: string, maxAttempts = 3) {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await client.zones.create({
account: { id: 'account-id' },
name,
type: 'full',
});
} catch (err) {
if (err instanceof Cloudflare.RateLimitError && attempt < maxAttempts) {
const retryAfter = parseInt(err.headers['retry-after'] || '5');
console.log(`Rate limited, waiting ${retryAfter}s (retry ${attempt}/${maxAttempts})`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
} else {
throw err;
}
}
}
}
```
## Conditional Update Pattern
```typescript
// Only update if zone is active
const zone = await client.zones.get({ zone_id: 'zone-id' });
if (zone.status === 'active') {
await client.zones.edit(zone.id, { paused: false });
}
```
## Batch with Error Handling
```typescript
// Process multiple zones, continue on errors
const results = await Promise.allSettled(
zoneIds.map(id => client.zones.get({ zone_id: id }))
);
results.forEach((result, i) => {
if (result.status === 'fulfilled') {
console.log(`Zone ${i}: ${result.value.name}`);
} else {
console.error(`Zone ${i} failed:`, result.reason.message);
}
});
```
## See Also
- [api.md](./api.md) - SDK client initialization, basic operations
- [gotchas.md](./gotchas.md) - Rate limits, common errors
- [configuration.md](./configuration.md) - SDK configuration options