Skip to content
cloudflare-api-orchestration logo

Cloudflare API Orchestration Skill

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...

SKILL.md

Full skill instructions

Cloudflare API Orchestration Skill

This skill enforces BooksTrack-specific API orchestration patterns for Cloudflare Workers.

Core Principles

1. Provider Orchestration (MANDATORY)

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
}

2. Provider Tagging (REQUIRED)

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 database

3. Error Handling Patterns

Implement 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
    });
  }
}

4. D1 Query Patterns

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();
}

5. KV Caching Strategy

Key naming convention:

namespace:entity:id

Examples:

  • book:isbn:9780134685991
  • search:query:swift+programming
  • user:profile:user123

Caching 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 };
}

6. Rate Limiting

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...
}

7. Circuit Breaker Pattern

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;
    }
  }
}

BooksTrack-Specific Patterns

Book Search API

// 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' }
    });
  }
}

Book Details API

// 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;
}

Anti-Patterns to Avoid

❌ Direct API Calls

// DON'T DO THIS
const response = await fetch('https://api.example.com/​books');

❌ Missing Provider Tags

// DON'T DO THIS
return { data: books }; // Missing provider metadata

❌ Unhandled Errors

// DON'T DO THIS
const result = await provider.fetch(); // No try-catch

❌ SQL Injection Vulnerabilities

// DON'T DO THIS
await env.DB.prepare(`SELECT * FROM books WHERE title = '${title}'`).first();

❌ No Caching Strategy

// DON'T DO THIS - always hitting live APIs
const result = await provider.fetch(); // No cache check

Validation Checklist

When implementing or reviewing Cloudflare Workers APIs, verify:

  • All API calls go through orchestration layer
  • Responses include provider tags
  • Fallback chains implemented (primary → secondary → cache)
  • D1 queries use prepared statements
  • KV keys follow naming convention
  • Rate limiting configured for public endpoints
  • Circuit breakers protect external services
  • Error handling provides useful context
  • Caching strategy reduces API calls
  • Logging captures provider failures

Integration with Code Review

This skill complements the code-review-grok subagent. When code review identifies orchestration violations, this skill provides the correct patterns to follow.


Async API Development (v2.0.64)

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:

  • Complex multi-provider orchestration
  • D1 schema migrations
  • KV→D1 data migrations
  • Comprehensive API security audits

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

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

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...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

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...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

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.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View