xiaohongshu
xiaohongshu
cloudflare-api-orchestration
Activates automatically when designing or implementing Cloudflare Workers APIs, orchestrating multi-provider API calls, implementing D1 database operations, or managing KV-based caching strategies. Ensures proper error handling, provider tagging, fallback chains, and orchestration patterns for B...
Full skill instructions
This skill enforces BooksTrack-specific API orchestration patterns for Cloudflare Workers.
NEVER make direct API calls without orchestration layer.
Correct pattern:
// orchestrator.js
export class APIOrchestrator {
async searchBooks(query, options = {}) {
const providers = [
{ name: 'google', fn: () => this.googleBooks.search(query) },
{ name: 'openlibrary', fn: () => this.openLibrary.search(query) }
];
for (const provider of providers) {
try {
const result = await provider.fn();
return {
...result,
provider: `orchestrated:${providers.map(p => p.name).join('+')}`,
cached: false
};
} catch (error) {
console.warn(`Provider ${provider.name} failed:`, error);
continue;
}
}
// Final fallback to cache
const cached = await this.kv.get(`book:${query}`);
if (cached) {
return {
...JSON.parse(cached),
provider: 'cache:kv',
cached: true
};
}
throw new Error('All providers failed');
}
}
Wrong pattern (FORBIDDEN):
// ❌ Direct API call without orchestration
async function searchBooks(query) {
const response = await fetch(`https://www.googleapis.com/books/v1/volumes?q=${query}`);
return response.json(); // Missing provider tag, no fallback, no caching
}
All responses MUST include provider metadata:
{
data: { /* actual response */ },
provider: "orchestrated:google+openlibrary", // Multi-provider
cached: false,
timestamp: Date.now()
}
Tag formats:
"orchestrated:google+openlibrary" - Successful multi-provider aggregation"google" - Single provider (fallback failed or only one available)"cache:kv" - Retrieved from KV cache"cache:d1" - Retrieved from D1 databaseImplement graceful degradation:
try {
// Primary provider
const result = await primaryProvider.fetch();
return { data: result, provider: 'primary', cached: false };
} catch (primaryError) {
console.warn('Primary provider failed:', primaryError);
try {
// Secondary provider
const result = await secondaryProvider.fetch();
return { data: result, provider: 'secondary', cached: false };
} catch (secondaryError) {
console.warn('Secondary provider failed:', secondaryError);
// Cache fallback
const cached = await cache.get(key);
if (cached) {
return { data: cached, provider: 'cache:kv', cached: true };
}
// Final error with context
throw new APIError('All providers exhausted', {
primaryError,
secondaryError,
key
});
}
}
Always use prepared statements:
// ✅ Correct - prepared statement
const result = await env.DB.prepare(
'SELECT * FROM books WHERE isbn = ?'
).bind(isbn).first();
// ❌ Wrong - SQL injection vulnerability
const result = await env.DB.prepare(
`SELECT * FROM books WHERE isbn = '${isbn}'`
).first();
Batch operations for efficiency:
// ✅ Correct - batch insert
const stmt = env.DB.prepare('INSERT INTO books (isbn, title) VALUES (?, ?)');
const batch = books.map(book => stmt.bind(book.isbn, book.title));
await env.DB.batch(batch);
// ❌ Wrong - individual inserts (slow)
for (const book of books) {
await env.DB.prepare('INSERT INTO books (isbn, title) VALUES (?, ?)')
.bind(book.isbn, book.title)
.run();
}
Key naming convention:
namespace:entity:id
Examples:
book:isbn:9780134685991search:query:swift+programminguser:profile:user123Caching pattern:
async function getCachedOrFetch(key, fetchFn, ttl = 3600) {
// Try cache first
const cached = await env.KV.get(key, { type: 'json' });
if (cached) {
return { ...cached, cached: true };
}
// Fetch from provider
const fresh = await fetchFn();
// Cache for TTL seconds
await env.KV.put(key, JSON.stringify(fresh), {
expirationTtl: ttl,
metadata: { cached_at: Date.now() }
});
return { ...fresh, cached: false };
}
Implement per-endpoint rate limits:
import { RateLimiter } from './rate-limiter';
const limiter = new RateLimiter({
search: { requests: 100, window: 60 }, // 100 req/min
details: { requests: 200, window: 60 } // 200 req/min
});
async function handleSearch(request, env) {
const clientId = request.headers.get('CF-Connecting-IP');
if (!await limiter.check('search', clientId)) {
return new Response('Rate limit exceeded', {
status: 429,
headers: {
'Retry-After': '60',
'X-RateLimit-Limit': '100',
'X-RateLimit-Remaining': '0'
}
});
}
// Process request...
}
Prevent cascading failures:
class CircuitBreaker {
constructor(threshold = 5, timeout = 60000) {
this.failureCount = 0;
this.threshold = threshold;
this.timeout = timeout;
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
this.nextAttempt = Date.now();
}
async call(fn) {
if (this.state === 'OPEN') {
if (Date.now() < this.nextAttempt) {
throw new Error('Circuit breaker OPEN');
}
this.state = 'HALF_OPEN';
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
onSuccess() {
this.failureCount = 0;
this.state = 'CLOSED';
}
onFailure() {
this.failureCount++;
if (this.failureCount >= this.threshold) {
this.state = 'OPEN';
this.nextAttempt = Date.now() + this.timeout;
}
}
}
// Route: GET /api/v2/books/search?q=...
export async function handleBookSearch(request, env) {
const url = new URL(request.url);
const query = url.searchParams.get('q');
if (!query) {
return new Response(JSON.stringify({ error: 'Missing query parameter' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
const orchestrator = new APIOrchestrator(env);
try {
const result = await orchestrator.searchBooks(query);
return new Response(JSON.stringify(result), {
status: 200,
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'public, max-age=3600',
'X-Provider': result.provider
}
});
} catch (error) {
console.error('Search failed:', error);
return new Response(JSON.stringify({
error: 'Search failed',
message: error.message
}), {
status: 500,
headers: { 'Content-Type': 'application/json' }
});
}
}
// Route: GET /api/v2/books/:isbn
export async function handleBookDetails(isbn, env) {
// Try D1 first (authoritative source)
const cached = await env.DB.prepare(
'SELECT * FROM books WHERE isbn = ?'
).bind(isbn).first();
if (cached) {
return {
...cached,
provider: 'cache:d1',
cached: true
};
}
// Fetch from providers
const orchestrator = new APIOrchestrator(env);
const result = await orchestrator.getBookByISBN(isbn);
// Store in D1 for future requests
await env.DB.prepare(
'INSERT OR REPLACE INTO books (isbn, title, author, data) VALUES (?, ?, ?, ?)'
).bind(isbn, result.title, result.author, JSON.stringify(result)).run();
return result;
}
// DON'T DO THIS
const response = await fetch('https://api.example.com/books');
// DON'T DO THIS
return { data: books }; // Missing provider metadata
// DON'T DO THIS
const result = await provider.fetch(); // No try-catch
// DON'T DO THIS
await env.DB.prepare(`SELECT * FROM books WHERE title = '${title}'`).first();
// DON'T DO THIS - always hitting live APIs
const result = await provider.fetch(); // No cache check
When implementing or reviewing Cloudflare Workers APIs, verify:
This skill complements the code-review-grok subagent. When code review identifies orchestration violations, this skill provides the correct patterns to follow.
Complex API implementations can run in background:
// Launch complex endpoint implementation in background
Task({
subagent_type: "cloudflare-specialist",
prompt: "Implement /api/v3/books/search with full orchestration, caching, rate limiting",
run_in_background: true
})
// Continue with other work (UI, tests)...
// Retrieve implementation when ready
TaskOutput({
task_id: "agent_xyz123",
block: true
})
Background-friendly tasks:
Recommended Option Pattern (v2.0.62):
When presenting API implementation choices:
options: [
{label: "Orchestrated (Recommended)", description: "Multi-provider with fallback"},
{label: "Single provider", description: "Google Books only"},
{label: "Cache-first", description: "D1/KV with lazy provider fetch"}
]
Last Updated: December 11, 2025 Maintained by: Claude Code PM System Related Agents: cloudflare-specialist, code-review-grok Claude Code Version: v2.0.65
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience