jpskill.com
🛠️ 開発・MCP コミュニティ

edge-computing-patterns

Deploy to edge runtimes (Cloudflare Workers, Vercel Edge, Deno Deploy) for globally distributed, low-latency applications. Master edge middleware, streaming, and runtime constraints for 2025+ edge computing.

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o edge-computing-patterns.zip https://jpskill.com/download/17245.zip && unzip -o edge-computing-patterns.zip && rm edge-computing-patterns.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17245.zip -OutFile "$d\edge-computing-patterns.zip"; Expand-Archive "$d\edge-computing-patterns.zip" -DestinationPath $d -Force; ri "$d\edge-computing-patterns.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して edge-computing-patterns.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → edge-computing-patterns フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Edge Computing Patterns

概要

Edge computing は、世界中のユーザーに近い場所でコードを実行し、レイテンシーを数秒からミリ秒に短縮します。このスキルでは、グローバルに分散されたアプリケーションを構築するための Cloudflare Workers、Vercel Edge Functions、および Deno Deploy のパターンについて説明します。

このスキルを使用するべき場合:

  • 50ms 未満のレイテンシーを必要とするグローバルアプリケーション
  • エッジでの認証/認可
  • A/B テストとフィーチャーフラグ
  • 地理的ルーティングとローカライゼーション
  • API レート制限と DDoS 防御
  • レスポンスの変換 (画像最適化、HTML の書き換え)

プラットフォームの比較

機能 Cloudflare Workers Vercel Edge Deno Deploy
コールドスタート <1ms <10ms <10ms
ロケーション 300+ 100+ 35+
ランタイム V8 Isolates V8 Isolates Deno
最大実行時間 30s (有料: 無制限) 25s 50ms-5min
無料枠 10万 req/日 10万 req/月 10万 req/月

Cloudflare Workers

// worker.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url)

    // Geo-routing
    const country = request.cf?.country || 'US'

    if (url.pathname === '/api/hello') {
      return new Response(JSON.stringify({
        message: `Hello from ${country}!`
      }), {
        headers: { 'Content-Type': 'application/json' }
      })
    }

    // Cache API
    const cache = caches.default
    let response = await cache.match(request)

    if (!response) {
      response = await fetch(request)
      // Cache for 1 hour
      response = new Response(response.body, response)
      response.headers.set('Cache-Control', 'max-age=3600')
      await cache.put(request, response.clone())
    }

    return response
  }
}

// Durable Objects for stateful edge
export class Counter {
  private state: DurableObjectState
  private count = 0

  constructor(state: DurableObjectState) {
    this.state = state
  }

  async fetch(request: Request) {
    const url = new URL(request.url)

    if (url.pathname === '/increment') {
      this.count++
      await this.state.storage.put('count', this.count)
    }

    return new Response(JSON.stringify({ count: this.count }))
  }
}

Vercel Edge Functions

// middleware.ts (Edge Middleware)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // A/B testing
  const bucket = Math.random() < 0.5 ? 'a' : 'b'
  const url = request.nextUrl.clone()
  url.searchParams.set('bucket', bucket)

  // Geo-location
  const country = request.geo?.country || 'US'

  const response = NextResponse.rewrite(url)
  response.cookies.set('bucket', bucket)
  response.headers.set('X-Country', country)

  return response
}

export const config = {
  matcher: '/experiment/:path*'
}

// Edge API Route
export const runtime = 'edge'

export async function GET(request: Request) {
  return new Response(JSON.stringify({
    timestamp: Date.now(),
    region: process.env.VERCEL_REGION
  }))
}

Edge Runtime の制約

✅ 利用可能:

  • fetch, Request, Response, Headers
  • URL, URLSearchParams
  • TextEncoder, TextDecoder
  • ReadableStream, WritableStream
  • crypto, SubtleCrypto
  • Web APIs (atob, btoa, setTimeout, etc.)

❌ 利用不可:

  • Node.js APIs (fs, path, child_process)
  • ネイティブモジュール
  • 一部の npm パッケージ
  • ファイルシステムへのアクセス

一般的なパターン

エッジでの認証

import { verify } from '@tsndr/cloudflare-worker-jwt'

export default {
  async fetch(request: Request, env: Env) {
    const token = request.headers.get('Authorization')?.replace('Bearer ', '')

    if (!token) {
      return new Response('Unauthorized', { status: 401 })
    }

    const isValid = await verify(token, env.JWT_SECRET)
    if (!isValid) {
      return new Response('Invalid token', { status: 403 })
    }

    // Proceed with authenticated request
    return fetch(request)
  }
}

レート制限

export default {
  async fetch(request: Request, env: Env) {
    const ip = request.headers.get('CF-Connecting-IP')
    const key = `ratelimit:${ip}`

    // Use KV for rate limiting
    const count = await env.KV.get(key)
    const currentCount = count ? parseInt(count) : 0

    if (currentCount >= 100) {
      return new Response('Rate limit exceeded', { status: 429 })
    }

    await env.KV.put(key, (currentCount + 1).toString(), {
      expirationTtl: 60 // 1 minute
    })

    return fetch(request)
  }
}

エッジキャッシュ

async function handleRequest(request: Request) {
  const cache = caches.default
  const cacheKey = new Request(request.url, request)

  // Try cache first
  let response = await cache.match(cacheKey)

  if (!response) {
    // Fetch from origin
    response = await fetch(request)

    // Cache successful responses
    if (response.status === 200) {
      response = new Response(response.body, response)
      response.headers.set('Cache-Control', 'max-age=3600')
      await cache.put(cacheKey, response.clone())
    }
  }

  return response
}

ベストプラクティス

  • ✅ バンドルサイズを小さく保つ (<1MB)
  • ✅ 大きなレスポンスにはストリーミングを使用する
  • ✅ エッジキャッシュを活用する (KV, Durable Objects)
  • ✅ エラーを適切に処理する (エッジエラーは回復できない)
  • ✅ コールドスタートとウォームスタートをテストする
  • ✅ エッジ関数のパフォーマンスを監視する
  • ✅ シークレットには環境変数を使用する
  • ✅ 適切な CORS ヘッダーを実装する

参考資料

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Edge Computing Patterns

Overview

Edge computing runs code closer to users worldwide, reducing latency from seconds to milliseconds. This skill covers Cloudflare Workers, Vercel Edge Functions, and Deno Deploy patterns for building globally distributed applications.

When to use this skill:

  • Global applications requiring <50ms latency
  • Authentication/authorization at the edge
  • A/B testing and feature flags
  • Geo-routing and localization
  • API rate limiting and DDoS protection
  • Transforming responses (image optimization, HTML rewriting)

Platform Comparison

Feature Cloudflare Workers Vercel Edge Deno Deploy
Cold Start <1ms <10ms <10ms
Locations 300+ 100+ 35+
Runtime V8 Isolates V8 Isolates Deno
Max Duration 30s (paid: unlimited) 25s 50ms-5min
Free Tier 100k req/day 100k req/month 100k req/month

Cloudflare Workers

// worker.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url)

    // Geo-routing
    const country = request.cf?.country || 'US'

    if (url.pathname === '/api/hello') {
      return new Response(JSON.stringify({
        message: `Hello from ${country}!`
      }), {
        headers: { 'Content-Type': 'application/json' }
      })
    }

    // Cache API
    const cache = caches.default
    let response = await cache.match(request)

    if (!response) {
      response = await fetch(request)
      // Cache for 1 hour
      response = new Response(response.body, response)
      response.headers.set('Cache-Control', 'max-age=3600')
      await cache.put(request, response.clone())
    }

    return response
  }
}

// Durable Objects for stateful edge
export class Counter {
  private state: DurableObjectState
  private count = 0

  constructor(state: DurableObjectState) {
    this.state = state
  }

  async fetch(request: Request) {
    const url = new URL(request.url)

    if (url.pathname === '/increment') {
      this.count++
      await this.state.storage.put('count', this.count)
    }

    return new Response(JSON.stringify({ count: this.count }))
  }
}

Vercel Edge Functions

// middleware.ts (Edge Middleware)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // A/B testing
  const bucket = Math.random() < 0.5 ? 'a' : 'b'
  const url = request.nextUrl.clone()
  url.searchParams.set('bucket', bucket)

  // Geo-location
  const country = request.geo?.country || 'US'

  const response = NextResponse.rewrite(url)
  response.cookies.set('bucket', bucket)
  response.headers.set('X-Country', country)

  return response
}

export const config = {
  matcher: '/experiment/:path*'
}

// Edge API Route
export const runtime = 'edge'

export async function GET(request: Request) {
  return new Response(JSON.stringify({
    timestamp: Date.now(),
    region: process.env.VERCEL_REGION
  }))
}

Edge Runtime Constraints

✅ Available:

  • fetch, Request, Response, Headers
  • URL, URLSearchParams
  • TextEncoder, TextDecoder
  • ReadableStream, WritableStream
  • crypto, SubtleCrypto
  • Web APIs (atob, btoa, setTimeout, etc.)

❌ Not Available:

  • Node.js APIs (fs, path, child_process)
  • Native modules
  • Some npm packages
  • File system access

Common Patterns

Authentication at Edge

import { verify } from '@tsndr/cloudflare-worker-jwt'

export default {
  async fetch(request: Request, env: Env) {
    const token = request.headers.get('Authorization')?.replace('Bearer ', '')

    if (!token) {
      return new Response('Unauthorized', { status: 401 })
    }

    const isValid = await verify(token, env.JWT_SECRET)
    if (!isValid) {
      return new Response('Invalid token', { status: 403 })
    }

    // Proceed with authenticated request
    return fetch(request)
  }
}

Rate Limiting

export default {
  async fetch(request: Request, env: Env) {
    const ip = request.headers.get('CF-Connecting-IP')
    const key = `ratelimit:${ip}`

    // Use KV for rate limiting
    const count = await env.KV.get(key)
    const currentCount = count ? parseInt(count) : 0

    if (currentCount >= 100) {
      return new Response('Rate limit exceeded', { status: 429 })
    }

    await env.KV.put(key, (currentCount + 1).toString(), {
      expirationTtl: 60 // 1 minute
    })

    return fetch(request)
  }
}

Edge Caching

async function handleRequest(request: Request) {
  const cache = caches.default
  const cacheKey = new Request(request.url, request)

  // Try cache first
  let response = await cache.match(cacheKey)

  if (!response) {
    // Fetch from origin
    response = await fetch(request)

    // Cache successful responses
    if (response.status === 200) {
      response = new Response(response.body, response)
      response.headers.set('Cache-Control', 'max-age=3600')
      await cache.put(cacheKey, response.clone())
    }
  }

  return response
}

Best Practices

  • ✅ Keep bundles small (<1MB)
  • ✅ Use streaming for large responses
  • ✅ Leverage edge caching (KV, Durable Objects)
  • ✅ Handle errors gracefully (edge errors can't be recovered)
  • ✅ Test cold starts and warm starts
  • ✅ Monitor edge function performance
  • ✅ Use environment variables for secrets
  • ✅ Implement proper CORS headers

Resources