CHAPTER 01 はじめに
小さなWebサービスを、自分で公開できるようになる
「イベントの申込みを受け付けたい」「自分の仕事に合うAIツールを作りたい」「作ったアプリを、ほかの人にも使ってもらいたい」。Cloudflareを学ぶと、こうしたアイデアを実際に使えるWebサービスにする方法が分かります。
画面を作るだけならできそうでも、公開するサーバー、データの保存先、アクセスが増えたときの対応まで考えると、急に難しく感じるかもしれません。Cloudflare、とくにWorkersの魅力は、小さなWebサービスに必要な機能を、一つずつ追加しながら始められること です。
最初の目標は、短いプログラムを書いて、アクセスすると結果が返るURLを一つ持つこと。その次に入力を受け取り、データを保存し、画面を付ける。Cloudflareの機能をすべて知ってから作り始める必要はありません。
この教材を読むことで目指す変化: 「こんなサービスがあったら便利だ」と思ったときに、必要な機能を考え、小さく作って試せるようになることです。Cloudflareは、そのための有力な選択肢です。
たとえば、こんなものから始められる
イベント・コミュニティー 自分の申込み受付を作る 案内ページから送られた名前や参加区分を保存し、確認結果を返す。慣れたら定員確認や管理画面を追加できます。
最初に学ぶこと:入力の受付と保存。実運用では認証や個人情報の管理も必要です。
仕事・個人の道具 用途を絞ったAIツールを作る 入力した文章を決まった形式に整理する、よく使う説明文の下書きを作る。自分の用途に合わせた画面と処理を作れます。
最初に学ぶこと:画面とAIの接続。AIの利用料金や送信する情報も管理します。
作品・情報の公開 画像や資料を配信する 作品紹介ページに画像を載せる、ダウンロード資料を配る。保存先と配信の仕組みを知ると、公開する量が増えたときにも選択肢が広がります。
最初に学ぶこと:静的ファイルの配信とR2。保存量・操作数は費用に影響します。
既存システムの改善 今あるサイトに機能を加える 特定のURLだけ別の処理にする、公開データをキャッシュする、外部サービスからの通知を受け取る。サイト全体の作り直しを伴わない使い方もできます。
最初に学ぶこと:URLの振り分けと、既存サーバーとの接続。
これらは製品の機能を組み合わせた制作例です。完成済みのサービスが自動的に手に入るわけではなく、必要な処理や権限を実装していきます。
Cloudflareを選ぶと、何が変わる?
1. 最初の公開までに、自分で用意するものを少なくできる
Workersでは、自分でサーバーを借りてOSを設定する工程を持たずに、コードを配置できます。最初は独自ドメインも不要です。まず一つ動かし、結果を見ながら学べる ため、「準備を終えるまで成果が見えない」という負担を小さくできます。
画面用のHTMLや画像もWorkersのStatic Assetsで配信でき、必要になったらデータベースやファイル保存を追加できます。画面とAPIを同じプロジェクトで扱える構成は、少人数で開発する場合にも試す価値があります。
公式資料:最初のWorkerを作る手順 / Static Assets
2. 複数の地域への配信を、共通の基盤に任せられる
Cloudflareは分散したネットワークでWeb通信やWorkersを処理します。利用者が増えるたびに自分で各地のサーバーを設置する方法とは、準備の仕方が変わります。広い地域の利用者に届けたいWebページや、短い処理のAPI では、この仕組みが役立ちます。
ただし、実際の速さは保存先や外部APIとの距離にも左右されます。「Cloudflareへ移せば必ず速くなる」とは限りません。どこへの通信が多いかを見て、小さい機能で測ることが大切です。
公式資料:Workersの実行モデル
3. 小さく試し、利用量に合わせて費用を考えられる
Workersには無料プランがあり、最初の学習や小規模な試作に使えます。ファイル保存のR2には、R2から直接インターネットへ送るデータの転送料が無料 という特徴があります。画像や資料を広く配信するサービスでは、費用を見直す理由になり得ます。
無料枠には上限があり、R2も保存量や読み書き操作は課金対象です。AIやログも別に考えます。比較するときは月額の表示だけでなく、自分のサービスの使われ方で、総額がどう変わるか を確認します。
公式資料:Workers料金 / R2料金
特に試してみる価値がある人: これから小さなWebサービスを作る人、少人数で画面とAPIを開発する人、公開ファイルの配信費用を見直したい人、既存サイトに一つ機能を足したい人。続いて、AIエージェントとの関係と、ほかのクラウドも含めた選び方を見ていきます。
CHAPTER 02 はじめに
なぜ今、AIエージェントの基盤として注目されるのか
AIに文章を書いてもらうだけでなく、資料を調べ、必要な処理を実行し、途中経過を保存して、仕事を先へ進めてもらう。そのようなAIエージェントを、自分のWebサービスとして提供する ための選択肢として、Cloudflareの役割が広がっています。
たとえば、イベントの資料を受け取り、案内文を作り、人が内容を確認したら公開するサービス。AIモデルを呼ぶ機能に加えて、資料の保存、処理の再開、承認待ち、実行履歴の確認が必要です。Cloudflareには、これらを組み合わせるためのサービスがあります。Workersを学ぶと、AIへの一度の質問から、継続して使えるアプリへ進むための基本が身に付きます。
まず区別したい、二つの「AIで作る」
開発するとき AIにアプリを作ってもらう 開発用AIがコードを書き、テストや公開手順を手伝います。完成するものは、普通の受付フォームやWebサイトでも構いません。公開を自動化するには、ツールの接続と適切な権限が必要です。
利用するとき アプリの中でAIが作業する 利用者の依頼に応じて、AIがツールを選び、処理を繰り返します。こちらがAIエージェントを動かす仕組みです。会話の状態、実行権限、費用、途中で失敗した場合の扱いまで設計します。
二つを組み合わせることもできます。ただし、Cloudflareを選ぶだけで、AIが無条件に正しいアプリを作って公開してくれるわけではありません。AIが作った結果を自分で確かめられること が、学ぶ価値の一つです。
2026年の発表から分かること
時期 公式に発表されたこと 初心者にとっての意味
5月19日 AnthropicのClaude Managed Agents向けにCloudflare Environmentsを提供する協業 Claude側がエージェントの処理を進め、Cloudflare側がコードやツールを実行する環境などを提供する。AIモデルと、その作業を実行する環境は別の役割。
8月4日 Agents Week期間中 Cloudflare Agentsを発表 エージェントを公開した後の、セッションや実行過程の観測・運用に重点が置かれている。
8月31日 Bot ManagementのAdaptive Intelligenceを発表 AIを動かす基盤に加えて、不正な自動アクセスへ対応する機能も拡充。発表時点では継続的な再学習が開始され、ほかの構成要素には今後の提供予定が含まれる。
9月3日 Managed Defenseの脆弱性発見・修復支援を招待制の早期提供として発表 OpenAI Daybreakモデルによる調査に、実際の通信・セキュリティ情報を組み合わせる。一般のWorkers無料機能や、無条件の自動修復とは異なる。
公式発表:Anthropicとの協業 / Cloudflare Agents / Adaptive Intelligence / 脆弱性発見・修復支援
Managed Defenseの発表では、GPT-5.6 Cyberを含むOpenAI Daybreakモデルを使用し、モデルの推論はOpenAI側で実行すると説明されています。修正案は検証と顧客のレビューを経る仕組みです。「Cloudflare上のAIが、すべての弱点を自動で直す」と受け取らないようにしましょう。
開発と運用、セキュリティという異なる分野で発表が続いたことは、Cloudflareを目にする機会が増える背景として考えられます。ただし、これは発表内容をもとにした見方 です。個人の周囲で評判が広がった原因や、開発者全体の支持の割合を示す調査ではありません。
エージェントに必要な機能を、どう分担する?
依頼を受けるWorkers / 画面
→ 考え、ツールを使うAIモデル + 実行処理
→ 保存・待機・再開DO / R2 / Workflows
→ 結果を確認する観測 / 人による承認
資料から案内文を作るエージェントの構成例。すべての製品を最初から使う必要はありません。
役割 主な選択肢 何を担当するか
AIの応答を得る Workers AI / 外部AI 文章生成などの推論。AI Gatewayは呼び出しのログや制御を担う。
エージェントを実装する Agents SDK 状態を持つエージェントを実装するSDK。Durable Objectsを利用する。
エージェントを観測・運用する Cloudflare Agents セッションやトレースを通じて、処理の経過や利用量を確認する。Agents SDKと同義ではない。
状態やファイルを残す Durable Objects / R2 個々のエージェントの状態や、資料・成果物を保存する。
複数段階の処理を続ける Workflows 再試行、外部イベント待ち、人の承認待ちなどを含む処理を進める。
コードやブラウザを動かす Sandbox / Browser Run / Dynamic Workers 順に、隔離されたコンテナでの実行、実ブラウザの操作、実行時に渡されたコードの隔離実行。用途と制約が異なる。
公式資料:Agents SDK / トレースと観測 / AgentsとWorkflows / Sandbox / Browser Run / Dynamic Workers
隔離された実行環境でも、外部へ送ってよい情報や、実行してよい操作は別に決めます。公開・送信・削除には必要に応じて承認を設け、モデル呼び出し回数と処理時間にも上限を持たせます。トレースには入力内容や機密情報が残り得るため、記録する対象を選びます。製品ごとに料金と利用条件があり、すべてを無料で使えるわけではありません。
AIを使う側だけでなく、情報を公開する側にも関係がある
Cloudflareは、AIによるアクセスをSearch(検索)、Training(学習)、Agent(利用者に代わる取得・操作) に分けて管理する仕組みも提供しています。目的が違えば、サイト運営者が許可したい範囲も違うためです。
2026年9月15日の更新: 新規ドメイン向けの推奨設定は、広告収益の有無で異なります。広告を使うサイトではSearchを許可、Trainingを「Disallow AI Training」、Agentを「広告のあるページでブロック」とする構成が示されています。広告を使わないサイトでは、各区分を許可する構成です。設定は変更できます。
「Disallow AI Training」は、学習への利用を拒否しつつ検索に残るための設定です。通信自体を止める「Block」とは異なり、対応するクローラーによる遵守が前提になります。検索と学習を兼ねるクローラーをBlockすると、検索にも影響します。古い発表だけを読んで「学習用は一律に遮断され、検索には影響しない」と判断しないでください。
最新の公式説明:2026年9月15日:検索とAI学習を区別する設定
話題になっていることと、自分に合うことを分けて考える
Cloudflareは以前からCDNやセキュリティで使われてきた会社です。最近の発表は、既存の実行・保存・通信の機能をエージェント開発へ広げる動きとして理解できます。株価やSNSの評判は関心の広がりを知る材料ですが、アプリが速くなること、安くなること、止まらないことの証明にはなりません。
これから作る人なら「AIで文章を整え、結果を保存する小さなアプリ」を試す。すでにAWSを使う人なら「新しいAI機能だけをWorkersで作り、既存DBと接続する」案を比較する。開発の手間、応答時間、総費用、復旧方法を自分の条件で確かめると、学習や移行の理由が具体的になります。
最初から自律的なエージェントを完成させる必要はありません。 まずは入力を受け取り、結果を返すWorkerを一つ作る。保存とAI呼び出しを加え、その後に複数段階の処理へ進む。この順序なら、便利さを確かめながら、動く理由も理解できます。
CHAPTER 03 はじめに
AWS・Google Cloudと、どう選び分ける?
Cloudflareを選ぶ価値が高いのは、自分が作りたいものと、その仕組みが合うときです。Webサービスの作り始めや配信の改善では有力な候補ですが、既存のアプリや大量のデータを扱う仕事では、AWSやGoogle Cloudが向く場合もあります。
AWSのLambdaやGoogle CloudのCloud Runも、サーバーの管理をサービス側に任せてコードを実行できます。「サーバー管理が不要」という点だけでは、Cloudflareだけの優位性にはなりません。 比較したいのは、公開・配信・保存まで含めて、自分の構成をどれだけ無理なく作れるかです。
公式資料:AWS Lambda / Google Cloud Runの実行環境
自分の目的から、候補を絞る
やりたいこと・今の状況 検討しやすい選択 その理由と、確認すること
小さなWebアプリやAPIを新しく作りたい Cloudflare Workers コードの実行、静的ファイルの配信、保存先を段階的に組み合わせられる。実行時間・メモリ・使うライブラリが対応範囲か確認する。
画像やダウンロード資料の配信費用を見直したい Cloudflare R2を比較候補に R2からの直接配信にはインターネット転送料がない。保存・操作・キャッシュの費用と、現在の契約条件を含めて比べる。
AWS上のDB・権限設定・社内ネットワークをすでに使っている AWS Lambda / ECS Fargateなどを継続する案 既存の接続や運用経験を活かせる。移行のための接続・権限・監視の作り直しが、得られる効果に見合うか確認する。
既存のコンテナや、大きなメモリを使う処理を動かしたい Google Cloud Run / AWS ECS Fargateなど アプリと実行に必要なものをまとめた「コンテナ」を動かし、CPU・メモリを指定できる。起動方法、時間制限、永続保存の条件も確認する。
大量の履歴をSQLで集計・分析したい Google CloudのBigQueryなどの分析基盤 大量データの分析用に設計されている。アプリのメモを保存するD1と、同じ役割だと考えない。
今のサービスは安定しており、明確な困り事がない 現行基盤を使い、新機能だけCloudflareで試す案 移行の作業とリスクを抑えながら、開発のしやすさを比較できる。
この表は各社の公式仕様をもとにした、教材としての選び方の提案です。速度・費用の実測比較や、すべてのサービスを網羅した順位表ではありません。
比較の根拠:AWS内でのLambdaとRDSの接続 / Fargateの実行条件 / Cloud Runのメモリ設定 / BigQueryの用途
Cloudflareの、不便になり得るところも知っておく
既存のプログラムを、そのまま動かせるとは限りません。 通常のWorkersにはメモリやCPU時間などの制約があり、Node.jsとの互換性にも範囲があります。OSの機能に強く依存する処理や、長時間の重い計算は、別の実行方法を検討します。CloudflareにもContainersという別サービスがありますが、この教材の通常のWorkersとは実行条件・料金を分けて考えます。
データを置く場所の設計は必要です。 Cloudflare側のAPIから、遠くのAWS上のデータベースへ何度も問い合わせれば、その通信が遅さの原因になることがあります。また、D1は既存のPostgreSQLやMySQLの完全な代替ではありません。既存DBを残して接続する方法も含めて判断します。
Cloudflare特有の機能を使うほど、移行時に直す部分は増えます。 KVやDurable Objectsなどを使ったコードやデータ構造は、別のクラウドへそのまま移せるとは限りません。独自機能で開発が楽になる効果と、将来の変更に必要な作業の両方を考えます。
障害対応や費用管理の仕事は残ります。 サーバーを直接管理しなくても、エラーの調査、データの復旧、利用者の権限、請求の確認は必要です。会社で採用するなら、監査・データの取扱地域・サポート契約なども条件に入れます。
公式資料:Workersの制限 / Node.js互換性 / Cloudflare Containers / 保存先の選び方
大規模障害から考える、一社への依存
2025年11月18日、Cloudflareでは中核の通信配信に大きな障害が発生しました。公式報告によると、攻撃ではなく、Bot Management用のファイル生成に関わる不具合が原因です。世界に分散した基盤でも、共通の仕組みの変更が広く影響することがあります。
個人の試作では、コードを手元にも保存し、重要なデータを取り出せるようにするところから始めます。仕事で使うなら、許容できる停止時間、バックアップの復元手順、別経路での障害案内を決めます。複数クラウドで動かす方法は費用と運用の複雑さも増すため、必要性に合わせて選びます。「障害後も話題だから安心」とは判断せず、便利さと停止時の影響を両方評価しましょう。
公式報告:2025年11月18日のCloudflareの障害
AWSからの乗り換えは、一つの機能で確かめられる
たとえば、既存アプリのDBはAWSに残し、新しい公開APIだけWorkersで試す。画像配信だけR2を比較する。既存サイトの手前で、特定のURLの処理やキャッシュだけをCloudflareに任せる。こうした部分的な採用から、移行する価値を確かめられます。
今の環境AWS / Google Cloud
→ 一つだけ試す新しいAPI / ファイル配信
→ 効果を比べる手間 / 速度 / 総費用
→ 合う範囲を採用併用も、段階移行も
一度に移し替えず、採用する理由を確認しながら範囲を広げる進め方です。
Workersから既存のPostgreSQLやMySQLへ接続するために、Hyperdriveを使う選択肢もあります。一方、クラウドをまたぐ通信には、接続方法、権限、転送料、障害の調査範囲が増えるという面もあります。S3からR2を検討するなら、使用中のS3 APIが対応しているかも確認します。
公式資料:既存DBを活かすHyperdrive / R2のS3 API互換範囲
最初に試すなら、「小さくて、結果が分かるもの」
これから学ぶ人は、名前を送ると挨拶を返すURLを一つ作ってみてください。すでにAWSなどを使っている人は、公開してよいデータを返す小さなAPIを一つ作り、今の方法と比べてみてください。作成と更新にどれくらい手間がかかるか、どこまで自分で理解して扱えるかが見えてきます。
まずは、一つのURLを動かすところから。 その経験があれば、Cloudflareの説明を読むだけでなく、自分の用途に合うかを判断できるようになります。この教材では、その最初の一歩から、保存・公開・運用までを順番に試していきます。
Hello Worldの実習へ進む → Webの仕組みから知りたい方は、このまま順に読み進めてください。
CHAPTER 04 基礎
何ができる? この教材の読み方
Cloudflare Workersを使うと、自分のプログラムをインターネット上で動かせます。たとえば、問い合わせを受け付けるAPI、画像を保存するサービス、AIへの質問を処理するアプリを作れます。
この教材では「Webの仕組みを知らない」状態から始め、短いプログラムを動かし、データ保存・公開・運用へ進みます。すべてのAPIを暗記する必要はありません。どこでコードが動き、何を保存し、何に料金がかかるか を説明できることが最初の目標です。
理解する Webの仕組みとWorkers DNS、CDN、HTTP、サーバーの意味から学びます。
動かす 最初のAPIを作る 文字を返すところから、URLやJSONを扱うコードへ進みます。
組み立てる 保存と運用を考える データの種類に合わせて製品を選び、認証や料金を確認します。
初回は、この順に読んでください
全体像〜Workersの仕組み: 図と太字を中心に読み、通信の流れをつかむ。Hello World〜環境変数: 手元のパソコンでコードを変え、結果を確かめる。保存・非同期・AI: まず比較表を読み、必要な製品を一つだけ試す。デプロイ〜実践: 小さなアプリを完成させ、公開前の条件を確認する。
このファイルだけで読めます。 図・スタイル・学習用の操作は内蔵されています。公式リンクを開く操作、開発ツールの導入、Cloudflareへの公開にはインターネット接続が必要です。教材内のシミュレーターは説明用で、Cloudflareに通信しません。
コードはJavaScriptを基本とし、設定にはコメントを書けるJSON形式のJSONC を使います。「ファイル全体」と書いた例は置き換え用、「断片」と書いた例は既存コードへの追加用です。実際に入力する値が必要な箇所には説明を添えます。
プログラミング経験がなくても進められますか? はい。ただし最初はコードを一度に理解しようとせず、文字列を一つ変えて結果を確認してください。変数・関数・条件分岐を簡単に説明してから使います。自分で機能を増やす段階ではJavaScriptの基礎を並行して学ぶと理解が深まります。
CHAPTER 05 基礎
Cloudflare全体を、通信とアプリの両方から見る
Cloudflareは、Web通信の配信・保護と、アプリを動かすためのサービスを提供しています。Workersは、その中の「プログラムを実行する」サービスです。
ブラウザ はWebページを見るアプリです。サーバー はブラウザなどから依頼を受け、データを返すプログラムやコンピューターを指します。元のWebサイトを動かしているサーバーをオリジンサーバー と呼びます。
利用者のブラウザページを要求
→ Cloudflare配信・保護・コード実行
→ 必要なときだけ 既存サーバー / DB / API
図1:Cloudflare経由の通信の概念図。Workers自身が応答を作る構成では、既存サーバーは不要です。
領域 主な製品・機能 何をする?
名前を解決する DNS ドメイン名から接続先を調べられるようにする。
配信を速くする CDN / Cache 保存済みのコンテンツを再利用し、元サーバーへのアクセスを減らす。
通信を保護する DDoS対策 / WAF / TLS 攻撃の緩和、リクエストの検査、通信の暗号化を行う。
アプリを動かす Workers / Static Assets 動的な処理とHTML・CSS・画像の配信を行う。
データを保持する KV / D1 / R2 / Durable Objects 用途に合った方法でデータや状態を保存する。
処理をつなぐ Queues / Cron Triggers 後で行う処理や、時刻に合わせた処理を起動する。
AIを利用する Workers AI / AI Gateway AIモデルの実行、またはAIへの呼び出しの管理を行う。
フロントエンドとバックエンド フロントエンド は利用者が操作する画面、バックエンド はデータ保存や権限確認などを行うサーバー側の処理です。ブラウザに渡したJavaScriptは利用者から見えます。APIキーや管理者権限が必要な処理は、Workersなどのバックエンドで扱います。
API はプログラム同士がデータや処理をやり取りするための決められた窓口です。「今日の予定を返すURL」「登録データを受け取るURL」などを作れます。Workersでは画面用HTMLもAPIのデータも返せます。
独自ドメインは、最初の実験には不要です。 Workersには workers.dev のURLを使う方法があります。ドメイン購入や、既存サイトのDNS変更をしなくても学習を始められます。
公式資料:Workersと公開URL
公式資料:静的ファイルも配信できるStatic Assets
CHAPTER 06 基礎
DNS・CDN・セキュリティを順に理解する
DNS:ドメイン名から接続先を調べる
www.example.com のような名前がドメイン名 です。通信先の識別に使うIPアドレスとの対応をDNSに登録します。A レコードはIPv4、AAAA はIPv6、CNAME は別のホスト名、MX はメール配送先、TXT は所有権確認などの文字情報に使います。
ドメインを購入することと、DNSを管理することは別の作業です。CloudflareでDNS全体を管理する一般的な方法では、ドメイン登録事業者の画面でネームサーバー を指定します。既存サイトやメールがある場合は、その前に必要なDNSレコードをそろえます。
Proxied:オレンジの雲 Web通信がCloudflareを通ります。そこでキャッシュや対応する保護機能を適用できます。
DNS only:灰色の雲 Cloudflareは名前の問い合わせに答えますが、Web通信は原則として接続先へ直接向かいます。
プロキシ化できるのは対応するA・AAAA・CNAMEレコードです。MXやTXTまでオレンジの雲にするわけではありません。 所有権確認用CNAMEなども用途に従って設定します。DNSをCloudflareに移しただけで、すべての通信が自動的に保護対象になるとは限りません。
公式資料:DNSのProxy status
CDN:同じ内容を何度も取りに行かない
CDN は複数の拠点からコンテンツを配信する仕組みです。キャッシュ は、取得した内容を保存して次のリクエストに再利用することです。保存済みの内容を使えればHIT 、使えず取得が必要ならMISS と呼びます。再利用できる期間はTTL で指定します。
1回目:画像を要求
→ MISS → 元サーバーから取得
→ キャッシュへ保存
2回目:同じ画像を要求
→ HIT → 保存済み画像を返す
→ 元サーバーへの通信を省く
図2:キャッシュが有効で、同じキャッシュ拠点に到達した場合の簡略例。
通常のCDNはHTMLやJSONをデフォルトではキャッシュしません 。ファイル拡張子、レスポンスヘッダー、ルールなどで動作が変わります。ログイン中の個人情報を含むページを共有キャッシュに入れると、他の人に見せてしまう可能性があります。
保存する場所を混同しない: ブラウザのキャッシュ、CloudflareのCDN、Workerが使うキャッシュは別のものです。「更新したのに変わらない」ときは、どの層が古い内容を返しているかを確認します。
公式資料:CDNの既定のキャッシュ動作
セキュリティ:それぞれ守る対象が異なる
仕組み 役割 アプリ側に残る仕事
TLS / HTTPS 通信を暗号化し、接続先を検証する。 誰に何を見せるかの判断。
DDoS対策 大量の攻撃通信によるサービス妨害を緩和する。 高コスト処理や利用者単位の使用量の制御。
WAF Webリクエストをルールで検査し、攻撃を遮断・緩和する。 入力検証、SQLの安全な実行、所有者確認。
認証・認可 本人確認と、許される操作の判定。 アプリに合った設計と、各APIでの検証。
既存オリジンを使う構成では、ブラウザ→CloudflareとCloudflare→オリジンの両区間を考えます。Full (strict) は後半のTLS証明書も検証するモードで、オリジン側に有効な証明書などの条件が必要です。これは独自のオリジンに接続する場合の設定です。
公式資料:WAF
公式資料:DDoS Protection
公式資料:Full (strict)の条件
CHAPTER 07 基礎
Workersは、イベントが来るとコードを実行する
Workerには「HTTPリクエストを受け取ったら何をするか」を書きます。Cloudflareが実行環境を管理するため、自分で常時稼働するサーバーを用意する必要はありません。
サーバーレス は、サーバーが存在しないという意味ではありません。開発者がOS更新や台数管理を直接行わず、サービス側の実行基盤に処理を任せる方式です。コード、データ、権限、エラー、料金の管理は開発者の仕事です。
イベントHTTP / 時刻 / キュー
→ 対応するハンドラーfetch / scheduled / queue
→ 応答・保存・後続処理
図3:ハンドラーは、イベントが起きたときに呼ばれる関数です。
V8 Isolatesと、保存してはいけない状態 JavaScript版Workersの実行環境は、V8のIsolate という分離された実行領域を使います。各処理のために新しい仮想マシンを起動する方式とは異なり、素早く起動できるよう設計されています。ただし、常に同じ実行領域が残る保証はありません。
たとえばコードの先頭に let count = 0 と書いても、世界中で共有される永続的なアクセス数にはなりません。別の実行領域では値が違い、再起動で失われることもあります。残したいデータは保存サービスへ、利用者ごとの一時変数はリクエスト内へ 置きます。
公式資料:Workersの実行モデル
「近くで動く」と「全処理が近くで完結する」は別 Cloudflareは分散したネットワークでリクエストを処理します。それでも、Workerから遠くのデータベースへ毎回問い合わせれば通信時間がかかります。利用者との距離だけでなく、データとの距離、問い合わせ回数、返す量 も速さに影響します。特定の国や拠点で必ず実行されると決めつけないでください。
CPU時間と待ち時間 計算 2ms APIを待つ 200ms 計算 3ms
この例の経過時間は205msですが、CPU時間は5msです。CPU時間は、コードの実行にCPUを使った時間 です。通信待ちが長い処理と、大きな配列の計算を続ける処理では、同じ経過時間でも消費が異なります。数値は理解のための例です。
Node.js用コードを使うとき WorkersはNode.jsそのものではなく、Workersランタイムで動きます。Node.js互換APIはありますが、すべての機能が使えるわけではありません。現在の公式資料では compatibility_date が2026-08-04以降ならNode.js互換機能が既定で有効 です。古い日付のプロジェクトでは設定が異なります。読み込めても実行できないAPIもあるため、依存ライブラリの使用部分を確認します。
公式資料:Node.js compatibility:日付による違い
公式資料:CPU時間などの制限
CHAPTER 08 実習
Hello World:まず一つ、動くものを作る
最初はパソコンの中で動かし、返す文字を変えてみましょう。公開は後の章で行います。
1. 準備するもの Cloudflareアカウント、対応するNode.js、コードを書くエディター、ターミナルを用意します。Macなら「ターミナル」アプリにコマンドを入力できます。コマンド はコンピューターに実行させる文字の指示です。
Node.jsにはnpmというパッケージ管理ツールが付属します。開発用ツールを動かすためにNode.jsを使いますが、Worker本体はWorkersランタイムで実行されます。Node.jsは公式サイトのサポート中のLTSを選び、Wranglerの現行要件も確認してください。
ターミナル:導入確認
node --version
npm --version
両方でバージョンが表示されれば準備を確認できます。command not found は、そのコマンドが見つからない状態です。導入後にターミナルを開き直し、再確認します。
公式資料:Wranglerの対応環境
2. プロジェクトを作る ターミナル:新規作成
npm create cloudflare@latest -- my-first-worker
cd my-first-worker
npm create が作成ツールを実行し、cd が作業フォルダーを移動します。作成時の選択は Hello World example → Worker only → JavaScript を基本にします。Gitを使うかは任意、最初のデプロイは No にします。対話画面の名称は更新で変わることがあります。
ファイル 役割 src/index.js実際に実行するWorkerのコード。 wrangler.jsonc名前、入口ファイル、互換日付、接続サービスの設定。 package.json開発ツールなどの依存関係。
3. コードを入れる src/index.js を次の内容に置き換えます。
src/index.js:ファイル全体
export default {
async fetch(request, env, ctx) {
return new Response("こんにちは、Workers!", {
headers: { "Content-Type": "text/plain; charset=utf-8" }
});
}
};
4. ローカルで起動する ターミナル:起動したままにする
npx wrangler dev
表示されたローカルURL(通常は http://localhost:8787)をブラウザで開きます。上の例なら「こんにちは、Workers!」が返る想定です。文字を変えて保存し、ページを再読み込みします。終了するときはターミナルで Control + C を押します。
ここでの成功条件: 表示されたことに加え、自分で文字を変え、その変更が反映されることを確かめます。localhost は自分のパソコンを指します。この段階では世界に公開されていません。
公式資料:公式CLI入門
コードを一行ずつ読む 記述 意味 export defaultこのファイルから、Workersが使うハンドラーを提供する。 async fetch(...)HTTPリクエストが来たときに呼ばれる関数。asyncは非同期処理を扱う宣言。 request届いたURL、メソッド、ヘッダー、本文など。 env設定値や接続した保存サービスなど。 ctx処理の実行に関する補助機能。 return new Response(...)呼び出し元に返す応答を作る。
async / awaitとは? 外部APIや保存処理の完了を待つとき、await を使います。結果がまだない状態を表すPromiseから、完了後の値を受け取れます。async 関数ではawaitを使えます。「待つ間ずっとCPUで計算を続ける」という意味ではありません。
CHAPTER 09 実習
Request / Response:Webのやり取りを読む
Webのやり取りは「リクエストを送る → レスポンスを返す」が基本です。Workersでは、その両方をコードで扱えます。
Request:何をしてほしい? URL :どの場所かMethod :何をするかHeaders :形式や認証などの付加情報Body :送るデータ
Response:結果はどうだった? Status :成功・失敗を表す番号Headers :返す形式やキャッシュ方針Body :HTML、JSON、画像など
URLの構成
https://api.example.com/api/hello?name=Hiro
└ 接続方式 ┘└ ホスト名 ┘└ パス ┘└ クエリ ┘
GET は取得、POST は送信・作成、PUT やPATCH は更新、DELETE は削除に使うのが一般的です。GETでページを開いただけでデータを消すような設計は避けます。
番号 意味 例 200 / 201 成功 / 作成成功 一覧が取得できた / 登録できた。 400 入力が不適切 必要な項目がない。 401 / 403 有効な認証がない / 操作が許可されない ログインが必要 / 他人のデータは編集不可。 404 / 405 対象なし / メソッド不許可 URLが違う / POST専用へGETした。 429 利用回数が多すぎる 短時間の集中アクセス。 500 / 502 内部エラー / 上流との通信などの問題 コードの例外 / 依存APIが失敗。
名前に応じたJSONを返す JSON は { "name": "Hiro" } のようにデータを表す形式です。次のコードでHello Worldを置き換え、/api/hello?name=Hiro を開いてください。
src/index.js:ファイル全体
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/api/hello") {
if (request.method !== "GET") {
return new Response("GETを使ってください", {
status: 405, headers: { Allow: "GET" }
});
}
const name = url.searchParams.get("name") || "ゲスト";
if (name.length > 40) {
return Response.json({ error: "名前は40文字以内です" }, {
status: 400
});
}
return Response.json({ message: `こんにちは、${name}さん!` }, {
headers: { "Cache-Control": "no-store" }
});
}
return new Response("ページが見つかりません", { status: 404 });
}
};
const は値に名前を付ける宣言、if は条件分岐です。new URL(...) でURLを分解し、pathname でパス、searchParams.get(...) でクエリ値を取り出します。|| の右側は、ここでは名前が空か未指定のときに使う値です。
公式資料:Request API
公式資料:Response API
POSTの本文を読む fetchハンドラー内の断片
const data = await request.json();
// 例:data.title が送信されたタイトル
// 形式だけでなく型・長さ・必要な項目も検証する
request.json() は、本文が不正なJSONなら例外になります。try / catch で扱い、400などを返します。本文は基本的に一度読むと消費されます。複数回読む設計や、大きなファイルを丸ごとメモリに載せる設計は避けます。後の実習では、小さいJSONに限定して扱います。
CHAPTER 10 基礎
ルーティングは、公開先とコード内の2段階
まず「どのWorkerへ届けるか」をCloudflare側で決め、その後「Worker内のどの処理を行うか」をパスやメソッドで決めます。
api.example.com/items
→ 公開先の設定Workerを選ぶ
→ コード内の分岐GET /items を処理
図4:ドメインの接続と、アプリ内のURL分岐は別々の設定です。
公開方法 向く場面 重要な条件 workers.dev最初の実験、個人・趣味のプロジェクト。 独自ドメインなしで始められる。本番の重要用途では公式はRouteかCustom Domainを推奨。 Custom Domain Worker自体がサイトやAPIの応答を作る。 自分のCloudflare上の有効なゾーンが必要。ホスト名全体をWorkerへ接続する。 Route 既存Webサーバーの前で処理を加える。 有効なゾーンと、対象ホストのプロキシ化されたDNSレコードが必要。
ゾーン はCloudflareで管理するドメインの設定単位です。Custom DomainではCloudflareがDNSと証明書を設定します。RouteではURLパターンを指定します。次の2例は用途が異なるので、必要な方だけを設定へ追加します。
wrangler.jsoncのプロパティ断片:Workerが応答を作る
"routes": [
{ "pattern": "api.example.com", "custom_domain": true }
]wrangler.jsoncのプロパティ断片:既存サイトの前に配置
"routes": [
{ "pattern": "www.example.com/api/*", "zone_name": "example.com" }
]
example.com は説明用ドメインです。自分の管理するドメインへ置き換えます。Custom Domainはホスト名単位なので、/items などの振り分けはコード側で行います。既存CNAMEと競合するなど、追加できない条件もあります。
既存サーバーの応答にヘッダーを追加する例 次は既存オリジンの前のRoute用です。fetch(request) で元サーバーに問い合わせます。ハンドラー名のfetchと、外向き通信のfetchは役割が異なります。
Route用:src/index.js全体
export default {
async fetch(request) {
const upstream = await fetch(request);
const response = new Response(upstream.body, upstream);
response.headers.set("X-App-Version", "1");
return response;
}
};
この例を、転送先がないCustom Domain構成にそのまま使わないでください。外部APIへ送る場合は、転送先URLと送信ヘッダーを明示します。
公式資料:公開先の選び方
公式資料:Custom Domains
公式資料:Routesの設定条件
CHAPTER 11 実習
環境変数・Secrets・Bindingsを使い分ける
コードに埋め込む必要のない値や接続先を、設定で渡します。env からアクセスできても、その種類と扱いは異なります。
種類 入れるもの コードからの使い方 環境変数(vars) アプリ名、非機密の設定値。 env.APP_NAMESecrets APIキー、機密トークン。 env.EXTERNAL_API_KEYBindings D1やKVなど、Workerに接続したサービス。 env.DB.prepare(...) など。
Binding はコード上の名前とリソースを接続する設定です。DBという名前は自動で生えるものではありません。設定に登録した名前とコードで使う名前を合わせます。varsやSecretsも、広い意味ではWorkerへ値を渡すBindingです。
基本の設定ファイル wrangler.jsonc:基本例
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-first-worker",
"main": "src/index.js",
"compatibility_date": "2026-09-17",
"vars": { "APP_NAME": "はじめてのWorkers" },
"observability": { "enabled": true }
}
compatibility_date はランタイムの互換動作の基準日です。デプロイ日を記録する欄ではありません。更新すると有効になる動作が変わることがあるため、既存アプリではテストしてから更新します。サンプルは教材確認日を使っています。
公式資料:互換日付の考え方
秘密は、ローカルと公開環境に別々に登録する ローカル開発では、設定ファイルと同じ場所に .dev.vars を作ります。以下の値はダミーです。ブラウザへ送るHTMLやJavaScriptに書かないでください。
.dev.vars:ローカル用
EXTERNAL_API_KEY="local-test-value".gitignoreに追加
.dev.vars*
.env*
公開環境への登録は次のコマンドで行い、対話入力欄に値を入力します。コマンドの引数に秘密そのものを記載する必要はありません。
ターミナル:公開環境のSecretを登録
npx wrangler secret put EXTERNAL_API_KEY
このコマンドは公開環境を変更します。 wrangler secret put は新しいWorkerバージョンを作り、直ちにデプロイします。すでに運用中なら変更のタイミングを考えます。ローカルの .dev.vars は自動アップロードされません。
Secretsでも、コードがレスポンスやログに出力すれば漏れます。console.log(env) や、秘密入りのエラーメッセージを返す処理は書かないでください。
公式資料:Secretsの登録・ローカル開発
開発・検証・本番を分ける 検証用の環境を staging 、実利用の環境を production と呼ぶことがあります。Wranglerの環境設定を使えば、同じコードを異なるリソースに接続できます。varsやBindingsは環境ごとに必要な設定を定義し、Secretsも対象環境へ登録します。検証中に本番データを書き換えない接続先 にすることが重要です。
公式資料:環境変数と環境ごとの設定
CHAPTER 12 応用
データをどこに置くかは、「どう読み、どう更新したいか」で決める
Cloudflareには保存先がいくつもあります。まず「設定を世界中で速く読みたい」「SQLで検索したい」「ファイルを置きたい」「同じ状態を順番に更新したい」のどれかを選びます。保存するデータの形より、読み書きの性質から選ぶと迷いません。
SQL はデータベースに検索や更新を指示する言語です。SQLite はD1などが使うデータベース技術。namespace はKVのデータを分ける単位、bucket はR2の保存単位です。以下の各例は独立した練習です。Hello Worldと同じ手順で別々のWorkerプロジェクトを作り、設定断片を基本のwrangler.jsoncへ追加してください。作成コマンドはCloudflare側にリソースを作りますが、通常のローカル開発では保存データをローカルに分けて扱います。
設定・キャッシュ KV
表形式のデータ D1
画像・動画・添付 R2
順番と共有状態 Durable Objects
KV: 読み込みの多い設定とキャッシュ
Workers KVは、キーに対して値を保存するグローバルなストアです。例えば
site:theme にサイト設定を、user:42:locale
に言語設定を置けます。世界中の拠点でキャッシュされるため、同じ値を何度も読む用途に向きます。
具体例:
管理画面で「今週の告知」を更新し、閲覧ページではその文章を読むだけにする。外部APIの結果を数分だけ保存し、毎回APIを呼ばないようにする。
選ばない場面:
書込み直後に、全地域の利用者が必ず新しい値を読む必要がある場面です。KVは結果整合性であり、他地域のキャッシュでは古い値や「まだ存在しない」という結果が60秒以上残ることがあります。残数、予約、投票数のような競合する更新には向きません。
以下はローカル実習用で、認証なしの最小例です。公開すると誰でも告知を変更できるため、そのまま本番へ出してはいけません。
// 単独例: POSTで書き、GETで読む
export default {
async fetch(request, env) {
if (request.method === "POST") {
await env.SETTINGS.put("announcement", "10月のイベントを公開しました");
return new Response("saved");
}
if (request.method !== "GET") return new Response("Method Not Allowed", { status: 405, headers: { Allow: "GET, POST" } });
const message = await env.SETTINGS.get("announcement");
return new Response(message ?? "お知らせはありません");
}
};
# ターミナル:namespaceを作成
npx wrangler kv namespace create SETTINGS
// wrangler.jsonc の断片。出力されたidを設定する
{ "kv_namespaces": [{ "binding": "SETTINGS", "id": "<NAMESPACE_ID>" }] }
実行準備:
開発環境と本番環境は別namespaceに分けます。ローカルの
wrangler dev
は通常KVをローカルにシミュレートします。本番namespaceへ接続する設定では、書込みも実データに反映されます。
公式: KV概要 /
整合性とキャッシュの仕組み
/
料金
D1: SQLで検索・集計するアプリのデータ
D1はSQLiteのSQLを使えるサーバーレスデータベースです。ユーザー、記事、コメント、申込みのように、列を持つデータを条件検索・結合・集計したいときに選びます。Workerからbinding経由で呼べるので、別のDB接続先を管理せずに始められます。
具体例:
イベント申込みフォームで、メールアドレスと参加区分を保存する。管理画面では「参加区分がオンラインの人だけ」をSQLで検索する。
設計上の注意:
1つのD1の実行インスタンスではクエリを一度に1本ずつ処理します。読み取りレプリカを使う構成は別途考えます。アクセスが集中して遅いクエリが続くと、待ち行列が埋まり
overloaded
エラーになり得ます。検索条件に使う列へインデックスを作り、全件走査を避けます。無料枠は「クエリ回数」ではなく、読んだ行500万/日・書いた行10万/日で消費します。
// fetchハンドラー内の断片:D1に申込みを登録する
const result = await env.DB.prepare(
"INSERT INTO registrations (email, attendance_type) VALUES (?1, ?2)"
).bind("hiro@example.com", "online").run();
return Response.json({ id: result.meta.last_row_id });
-- 事前に一度だけ実行するSQL(migrationファイルに保存)
CREATE TABLE registrations (
id INTEGER PRIMARY KEY,
email TEXT NOT NULL,
attendance_type TEXT NOT NULL
);
CREATE INDEX idx_registrations_type ON registrations(attendance_type);
実行準備:
wrangler d1 create app-db でDBを作り、設定ファイルの
d1_databases に binding: "DB" と
database_id
を登録します。スキーマはmigrationファイルとして管理し、ローカルと本番へ同じ順で適用します。
公式: D1概要 /
上限・並行性
/
料金
R2: 画像、動画、添付ファイルをオブジェクトとして保存する
R2はS3互換のオブジェクトストレージです。写真、PDF、音声、動画、バックアップ、生成AIの出力のように、ひとまとまりのファイルを置く用途に合います。ファイルそのものをD1やKVへ押し込むのではなく、R2へ置いて、D1にはファイル名・所有者・公開状態などのメタデータを持たせるのが基本形です。
具体例: 利用者がアップロードしたプロフィール画像を
avatars/42.jpg としてR2へ保存し、D1の
users テーブルにはそのキーだけを保存する。
費用の注意:
R2から直接インターネットへ出すegressは無料ですが、保存量と操作数には料金があります。頻繁に読まれる小さなファイルを大量に扱う場合は、Class
B操作数も見積もります。Infrequent
Accessは取得料と最低30日保存があり、無料枠の対象はStandardだけです。
以下はローカル実習用で、認証なし・本文サイズ制限なしの最小例です。小さいテキストだけで試し、このまま公開しないでください。この例は全体をメモリに読み込みます。大きいファイルには長さが分かるストリームやマルチパート処理などを検討します。実サービスではサイズ・形式を検証し、誰がどのキーを読み書きできるかをWorker内で認証・認可します。アップロードと配信を別Workerにすることもできますが、必須ではありません。
// 単独例: PUTで本文を保存し、GETで同じキーを読む
export default {
async fetch(request, env) {
const url = new URL(request.url);
const key = url.pathname.replace(/^\//, "") || "sample.txt";
if (request.method === "GET") {
const object = await env.FILES.get(key);
return object ? new Response(object.body, {
headers: { "Content-Type": "text/plain; charset=utf-8", "X-Content-Type-Options": "nosniff" }
}) : new Response("Not Found", { status: 404 });
}
if (request.method !== "PUT") return new Response("Method Not Allowed", { status: 405 });
// 小さいテキスト用。全文をメモリに読み込む。
await env.FILES.put(key, await request.arrayBuffer(), {
httpMetadata: { contentType: request.headers.get("content-type") ?? "text/plain" }
});
return Response.json({ key });
}
};
# ターミナル:bucketを作成
npx wrangler r2 bucket create learning-files
// wrangler.jsonc の断片
{ "r2_buckets": [{ "binding": "FILES", "bucket_name": "learning-files" }] }
実行準備: DashboardでR2
subscriptionを有効にしてbucketを作成します。公開配信する場合も、必要な認可をWorkerへ実装します。ローカルではR2をシミュレートでき、remote
bindingへ切り替えた場合の操作は実bucketのデータと料金に影響します。
公式:
R2開始方法
/
料金と無料枠
Durable Objects: 1つの状態を、みんなで矛盾なく使う
Durable
Object(DO)は、特定のIDに対応する1つのオブジェクトが計算と保存を担当する仕組みです。たとえば「チャットルーム
room-a」「商品 SKU-123」「共同編集する文書
doc-9」のように、同じ状態へ複数人が同時に触れる場面で使います。各IDへの処理を集めるため、更新の順序を管理できます。
具体例: 先着10名の予約枠を減らす。通常のKVで
remaining
を読んでから書くと、同時アクセスで二重予約が起き得ます。予約対象ごとにDOへ依頼すれば、残枠の確認と減算を同じ場所で順番に扱えます。
DOでも、コードの組み方は重要です。 外部APIをawaitしている間には別のリクエストが進む場合があります。下の例は、カウントの更新と取得の間に外部通信を挟まない同期SQLです。複数の変更を一まとまりにする場合は、トランザクションなどの仕組みも確認します。
公式:DOの並行処理とトランザクション
KVとの関係:
「世界中で素早く読む公開設定」はKV、「同じキーへの更新を競合なく決める」はDOです。DOで確定した結果をKVへ配る設計もありますが、KV側の読み取りは引き続き結果整合性です。
以下はローカル学習用の完全な最小例です。入口Workerはすべて同じ名前のObjectへPOSTを転送します。本番の予約やチャットでは、Object名の決め方と入口の認証・認可を設計します。この例には認証を実装していません。
// src/index.js: 入口WorkerとSQLite Durable Object
import { DurableObject } from "cloudflare:workers";
export class Counter extends DurableObject {
constructor(ctx, env) {
super(ctx, env);
this.sql = ctx.storage.sql;
this.sql.exec("CREATE TABLE IF NOT EXISTS state (key TEXT PRIMARY KEY, value INTEGER NOT NULL)");
this.sql.exec("INSERT OR IGNORE INTO state (key, value) VALUES (?, ?)", "visits", 0);
}
async fetch(request) {
if (request.method !== "POST") return new Response("Method Not Allowed", { status: 405 });
this.sql.exec("UPDATE state SET value = value + 1 WHERE key = ?", "visits");
const row = this.sql.exec("SELECT value FROM state WHERE key = ?", "visits").one();
return Response.json({ visits: row.value });
}
}
export default {
async fetch(request, env) {
if (request.method !== "POST") return new Response("POST / で数える", { status: 405 });
const id = env.COUNTER.idFromName("learning-counter");
return env.COUNTER.get(id).fetch(request);
}
};
// wrangler.jsonc: bindingとSQLite migrationを同じデプロイに含める
{
"name": "learning-counter",
"main": "src/index.js",
"compatibility_date": "2026-09-17",
"durable_objects": {
"bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
},
"migrations": [{ "tag": "v1", "new_sqlite_classes": ["Counter"] }]
}
実行準備: Hello Worldと同じ手順でWorker onlyのJavaScriptプロジェクトを作成し、この2ファイルに置き換え、
npx wrangler dev で起動します。別のターミナルから curl -X POST http://localhost:8787/ を繰り返し、visitsが増えることを確認します。新規クラスはSQLiteバックエンドが推奨され、Freeで利用できるDOもSQLiteのみです。クラス名やmigrationタグを途中で不用意に変更すると、既存状態を意図どおり引き継げないため、リリース前にmigrationを確認します。
公式:
Durable Objects概要
/
料金
CHAPTER 13 応用
待たせない処理と、決まった時刻の処理を分ける
利用者の画面をすぐ返したいとき、重い処理はQueuesへ渡します。毎日・毎時の処理はCron
Triggersで起動します。どちらもWorkerを動かしますが、Queuesは「届いた仕事」、Cronは「時刻」がきっかけです。
Producer は仕事をキューへ送る側、Consumer は取り出して処理する側です。Dead Letter Queue(DLQ) は、指定回数の再試行後も失敗した仕事の送り先です。DLQを設定し、そこに届いた仕事を調査・復旧する手順も用意します。
フォーム送信 Worker
→
Queues 仕事を保管
→
Consumer Worker 後で実行
ctx.waitUntil()とQueuesは別の仕組みです。 waitUntilは応答後にも短い処理を続ける補助機能で、HTTPでは応答送信や切断後、最大30秒まで延長できます。永続的な仕事の保管や自動再試行を保証するものではありません。失敗した仕事を残して再試行したい場合はQueuesなどを検討します。
公式:ContextとwaitUntil
Queues: 受け付けた処理を非同期に実行する
Queuesはメッセージを保存して非同期に処理するキューです。フォーム送信を受けたWorkerが「確認メールを送る」「画像を変換する」「外部サービスへ同期する」という仕事を積み、Consumer
Workerが後で取り出します。最初のHTTP応答を外部APIの遅さから切り離せます。
具体例:
申込み完了画面はすぐ返し、メール配信だけをQueueへ送る。メールサービスが一時的に失敗しても、Consumerは再試行できます。何度も失敗するメッセージはDead
Letter Queueへ送り、運用者が確認します。
設計上の注意:
Consumerは少なくとも1回の配信を前提にします。同じメッセージが再試行で届いても二重メールや二重課金にならないよう、外部サービス側の冪等キーなどを使って処理を冪等にします。D1へIDを記録するだけでは、外部送信のexactly-onceを保証できません。1メッセージは128
KBまでです。通常の配信は書込み・読取り・削除の約3操作なので、無料枠は「メッセージ1万件/日」ではありません。
// src/index.js:ファイル全体。ローカル学習用・認証なし。
export default {
async fetch(request, env) {
if (request.method !== "POST") {
return new Response("POSTを使ってください", {
status: 405, headers: { Allow: "POST" }
});
}
await env.MAIL_QUEUE.send({
eventId: crypto.randomUUID(), task: "send-confirmation"
});
return new Response("queued", { status: 202 });
},
async queue(batch, env) {
for (const message of batch.messages) {
// 学習用のログ出力。メール送信は行わない。
console.log("received", message.body.eventId, message.body.task);
message.ack();
}
}
};
# ターミナル:QueueとDLQを作成する
npx wrangler queues create mail-jobs
npx wrangler queues create mail-jobs-dlq
// wrangler.jsoncへの追加設定:同じWorkerにproducer/consumerを置く
{
"queues": {
"producers": [{ "binding": "MAIL_QUEUE", "queue": "mail-jobs" }],
"consumers": [{
"queue": "mail-jobs", "max_batch_size": 10, "max_batch_timeout": 5,
"max_retries": 3, "dead_letter_queue": "mail-jobs-dlq"
}]
}
}
実行準備: Queueを作成し、producer側は
queues.producers、consumer側は
queues.consumers
を設定します。実サービスで外部メールAPIを呼ぶ部分は、相手サービスの冪等キー、失敗時の記録、DLQからの復旧手順を追加します。Freeは操作10,000/日、保持期間は固定24時間です。
公式:
Queues開始方法
/
料金
/
上限
Cron Triggers: 決まった時刻にWorkerを起動する
Cron式は「分・時・日・月・曜日」の5項目で時刻の条件を表します。* は毎回を意味します。Cron Triggersはこの式でWorkerの
scheduled()
handlerを動かします。毎朝のニュース収集、毎時の古いデータ掃除、毎晩の集計、期限切れの通知などに使います。HTTPアクセスがなくてもWorkerを実行できるのが特徴です。
具体例:
日本時間の毎朝9時に前日分を集計したい場合、UTCで考えます。日本標準時はUTC+9なので、UTC
0時を指定する
0 0 * * *
が毎日9時に当たります。夏時間を使う地域では時差変更も考慮します。
運用上の注意:
CronはUTCで実行され、厳密な秒単位の実行保証ではありません。設定をWranglerで管理するWorkerでは、Dashboardと設定ファイルを混在させません。Wranglerのデプロイは指定したTrigger一覧で以前の設定を置換し、空配列
crons: [] はすべて削除します。
// 単独例: 毎日UTC 0:00(日本時間09:00)に動くWorker
export default {
async scheduled(controller, env, ctx) {
console.log("daily summary started", new Date().toISOString());
}
};
// wrangler.jsonc の断片
{
"triggers": {
"crons": ["0 0 * * *"]
}
}
実行準備: Workerに
scheduled()
を実装し、設定ファイルへcron式を追加してデプロイします。Freeはアカウントあたり5
Triggerまでで、WorkerのCPU上限も通常10
msです。重い処理はCronからQueuesへ仕事を積み、Consumerに分けると失敗時の再試行と時間管理がしやすくなります。
公式:
Cron Triggers
/
Workers料金
/
Workers上限
CHAPTER 14 応用
AIを実行するWorkers AIと、AI呼び出しを整えるAI Gateway
Workers AIはCloudflare上でモデルを推論するサービスです。AI
Gatewayは、Cloudflareや外部AIプロバイダーへの呼び出しを記録・キャッシュ・制限する入口です。両者は競合せず、Workers
AIをAI Gateway経由で呼ぶこともできます。
推論 は学習済みモデルへ入力を渡して結果を得ることです。LLM は文章などを扱う大規模言語モデル、GPU は並列計算が得意な計算装置。埋め込み は文章などを数値の列へ変換し、意味の近さを比較しやすくする方法です。
アプリのWorker
→
AI Gateway ログ・制御・キャッシュ
→
Workers AI または 外部AIプロバイダー
Workers AI: CloudflareのGPUでモデルを推論する
Workers
AIでは、LLM、埋め込み、画像、音声などのモデルをサーバーレスGPUで実行します。Worker、Pages、Cloudflare
APIから呼べるため、GPUサーバーの確保やスケールを自分で管理せずにAI機能を組み込めます。
具体例:
問い合わせ文を埋め込みモデルでベクトル化して検索に使う。短い要約を生成する。音声ファイルを文字起こしする。まず1つの入力と1つのモデルで試し、応答時間と出力品質を確かめてから画面に組み込みます。
費用と可用性の注意: 無料枠は「10,000
Neurons/日」です。Neuronはモデル別のGPU計算量で、リクエスト数ではありません。入出力の長さなどで消費量が変わります。Freeは日次枠を超えると利用が止まり、Paidでは超過分が従量課金されます。一部の計算負荷が高いモデルはFreeで利用できずPaidが必要です。利用前にモデルごとの入力・出力料金とライセンス条件を確認します。
// 単独例: Workers AI bindingでチャットモデルを呼ぶ
export default {
async fetch(request, env) {
const answer = await env.AI.run("@cf/meta/llama-3.2-1b-instruct", {
messages: [
{ role: "system", content: "日本語で短く答えてください。" },
{ role: "user", content: "Cloudflare Workersとは何ですか?" }
],
max_tokens: 120
});
return Response.json(answer);
}
};
実行準備: 設定ファイルへ
"ai": { "binding": "AI", "remote": true }
を追加します。固定したモデルIDで開発を始め、実サービスでは入力長・出力長・日次Neuron利用量をDashboardで監視します。AIモデルはローカルにはシミュレートされず、wrangler dev
からの推論もリモートで実行され、Neuronの利用枠を消費し、プランと使用量によって課金されます。max_tokens
のように出力上限を置き、秘密情報をプロンプトへ直接入れません。
公式:
Workers AI概要 / 例で使うモデルの仕様
/
料金とNeuron
/
ローカル開発とリモートAI
/
Paid必須モデルの告知
AI Gateway: AI呼び出しの記録、キャッシュ、制限を一か所に置く
AI
Gatewayはモデルそのものを提供する代わりに、AIへのリクエストを通す入口です。OpenAI、Anthropic、Google
AI Studio、Workers
AIなどをまとめ、分析、永続ログ、キャッシュ、レート制限、認証、Unified
Billingを適用できます。複数のAIを試すアプリや、利用量を把握したいチームに向きます。
具体例:
同じ質問が短時間に繰り返されるFAQではキャッシュを有効にし、AIへの重複呼び出しを減らす。ログからプロンプト、応答時間、失敗率を確認して改善する。利用者ごとの制限をしたい場合は、Gatewayのレート制限だけに頼らず、Worker側で利用者を認証して識別し、そのIDに基づく制限も実装します。
大事な区別: AI
Gatewayのコア機能は無料でも、推論そのものが無料になるわけではありません。外部プロバイダーをUnified
Billingで使う場合は、Cloudflareクレジットを購入し、購入額に5%手数料が加わります。GuardrailsはWorkers
AIの推論として消費されます。ログに個人情報や機密文を残す設計は、保存方針を決めてから有効にします。
// fetchハンドラー内の断片:AI呼び出しへGatewayを追加する
const answer = await env.AI.run(
"@cf/meta/llama-3.2-1b-instruct",
{ prompt: "Cloudflare Workersを1文で説明して", max_tokens: 80 },
{
gateway: {
id: "learning-gateway", // Dashboardで作った同一アカウントのGateway名
skipCache: false,
cacheTtl: 300
}
}
);
return Response.json(answer);
実行準備: Workers AI
bindingを設定し、DashboardでGatewayを作成してその名前を
gateway.id
に指定します。最初はテスト用Gatewayで、ログに残る内容とエラー時の振る舞いを確認します。Freeの永続ログは全Gateway合計10万件、作成できるGatewayは10個です。外部モデルをUnified
Billingで呼ぶ場合は、クレジット残高と自動チャージ設定も確認します。
公式:
Workers AIとの連携
/
Gatewayを指定するbinding例
/
AI Gateway料金
/
上限
確認したいこと
最初に見る場所
Cloudflareのモデルを自分のWorkerで動かしたい
Workers AI。モデル別Neuron消費とFree利用可否を確認する。
OpenAIなど複数社の利用量を一か所で追いたい
AI Gateway。ログの機密性、レート制限、課金経路を決める。
生成に時間がかかり画面を待たせたくない
Workerで受付 → Queuesへ投入 → ConsumerからAIを呼ぶ。
毎朝のAI要約を作りたい
Cron Triggerで起動し、長い処理はQueuesへ渡す。
CHAPTER 15 実習
デプロイ・デバッグ・ログで動作を確かめる
デプロイとは、コードや設定を実行環境へ配置することです。コマンドが成功した後も、公開URLで期待どおりに動くかを確認します。
手元で修正
→ ローカルで確認
→ 公開環境へ配置
→ 公開URL・ログを確認
図5:デプロイの成功と、アプリの動作確認は別の確認です。
最初の公開 Hello Worldや名前を返すAPIなど、公開してよい内容のWorkerで実行します。
ターミナル:ログインと公開
npx wrangler login
npx wrangler deploy
ログインではブラウザでCloudflareアカウントを認証します。公開後に表示されるURLを開いて確認してください。学習例では https://my-first-worker.<自分のサブドメイン>.workers.dev のような形式です。API例ならその末尾に /api/hello?name=Hiro を付けます。
確認 試すこと 正常系 正しいURL・メソッド・入力で、期待するデータが返る。 入力エラー 長すぎる文字、欠けた項目、不正JSONを送っても安全に失敗する。 境界 存在しないURLや許可しないメソッドに、適切な応答が返る。 本番接続 本番のBindings・Secrets・データがそろっている。
公式資料:Wranglerでの公開手順
ログを見る ターミナル:公開Workerのリアルタイムログ
npx wrangler tailfetchハンドラー内の断片:機密情報を含めない
console.log({ event: "request", method: request.method,
path: new URL(request.url).pathname });
保存して後から検索するWorkers Logsは、"observability": { "enabled": true } を設定し、再デプロイします。ダッシュボードの対象WorkerのObservability で確認できます。ローカルのログと公開環境のログを混同しないでください。
ログには保存期間と使用量の制約があります。サンプリングは記録するリクエストの割合を下げる機能です。全件を残しているとは限らないため、「ログがないから呼び出されていない」とは断定できません。トークン、本文全文、個人情報を安易に記録しない設計にします。
公式資料:Workers Logsの有効化と検索
公式資料:ログの種類
困ったときは、症状から調べる 症状 まず確認する場所 ローカルURLが開かない 起動中のターミナル、表示されたポート番号、停止していないか。 404 URLのパス・大文字小文字と、コードの条件が一致しているか。 405 ブラウザのGETでPOST専用のURLを開いていないか。 env.DBが未定義 Binding名、選択した環境、設定ファイル。 no such table D1のスキーマを、ローカル・リモートの正しい方に適用したか。 1102などの資源制限エラー CPUやメモリの使用量、大きなデータの読み込み。 ブラウザだけ失敗する 開発者ツールのNetwork、CORS、Cookie、実際のステータス。 公開版だけ失敗する 公開先のSecrets、Bindings、外部サービスの権限。
デバッガー では途中で処理を止め、変数を調べられます。まず再現する入力を一つに絞り、ローカルのログやDevToolsで確認すると原因を追いやすくなります。
更新で壊れたときのために ソースをGitで管理し、変更前の状態へ戻せるようにします。Workersのバージョン・デプロイ管理も利用できます。ただしコードを戻しても、データベースに行った変更や外部への送信は元に戻りません。DB変更は互換性と復旧方法を別に検討します。
CHAPTER 16 基礎
料金と制限:何を数えているかを理解する
Workersの料金は、主にリクエスト数とCPU時間で考えます。保存サービス、ログ、AIなどは、それぞれの使用量も確認します。
確認日:2026年9月17日。 以下は公式ドキュメントで確認した通常のWorkers Free / Paid(Standard)の代表値です。金額は米ドル。税・為替・個別契約・他サービス料金は含みません。申し込み前にはリンク先で再確認してください。
項目 Free Paid / Standard 基本料金 $0 アカウントあたり月額最低 $5 リクエスト 1日100,000件 月10,000,000件込み 超過100万件あたり $0.30 CPU時間 呼び出しあたり10ms 月30,000,000 CPU-ms込み 超過100万CPU-msあたり $0.02
Freeの日次リセットはUTCの0時です。日本時間では9時に相当します。Webサイト向けのPro / Businessと、Workers Paidは別のプラン として確認してください。
初期値の例では、月2,000万回 × 5ms = 1億CPU-ms。基本 $5 + リクエスト超過 $3 + CPU超過 $1.40 = 月 $9.40 です。これは見積もり例であり、実請求の保証ではありません。
通常のStatic Assetsへの直接のリクエストは無料・無制限です。ただしWorkers Cachingを有効にした場合は、キャッシュから返るリクエストも課金対象 になります。キャッシュHITではWorkerのCPU実行は課金されません。構成による違いを確認してください。
公式資料:Workersの料金・キャッシュ課金の注記
無料枠と、実行上の制限は別 代表的な制限 現在の値・読み方 メモリ Free / Paidともに128MB。大きいファイルはストリーム処理を検討。 PaidのHTTPリクエストのCPU 既定30秒。設定可能な上限は5分。Freeの10msとは別。 同時に開く外向き接続 1リクエストあたり6。外部サービスの応答本文の扱いにも注意。 Subrequest 外向きfetchなど。既定でFree 50 / Paid 10,000回(1リクエストあたり)。 受信本文のサイズ WorkersのプランではなくCloudflare側のプランにも依存。Free / Proでは100MB。
HTTPの経過時間とCPU時間の制限は異なります。CronやQueueには別の実行条件があるため、HTTPの上限をそのまま当てはめません。大きな本文を受け付けられても、全体をメモリに読み込めるとは限りません。
公式資料:最新の制限一覧
意図しない使用量を減らす Paidでは1回あたりのCPU上限を設定できます。次は100msという説明用の値です。必要な処理に足りるか計測して決めます。これは月額の支出上限ではありません。 呼び出し回数、保存量、AI利用などは別に制御します。
wrangler.jsoncのプロパティ断片:Paid向け
"limits": { "cpu_ms": 100 }
料金の確認では「何回呼ばれるか」「何を何回読み書きするか」「再試行が何回起こるか」を書き出します。ログの全件保存、D1の大量走査、R2の大量操作、AIの長い入出力も、アプリの総額に影響します。
CHAPTER 17 基礎
公開前に、入力・権限・秘密を確認する
Cloudflareが通信を保護していても、「他人のデータを編集してよいか」はアプリが判断します。小さいAPIでも、公開する前に境界を決めます。
認証:誰か ログインセッションや署名付きトークンなどで本人を確認します。IDの文字列が届いただけでは本人確認になりません。
認可:何をしてよいか ログイン済みでも、別の利用者のメモを読んだり編集したりできないよう、対象データの所有者を確認します。
実装で押さえる7点 入力: 型、長さ、許可値、本文サイズを検証する。JSONを読めたことと、安全な入力であることは別。SQL: 入力をSQL文字列へ連結せず、prepare(...).bind(...) で値を渡す。HTML: 利用者入力をHTMLへそのまま埋め込まない。文字の表示には textContent などを使う。秘密: Secretsに登録し、ブラウザやログへ返さない。漏れたキーは削除だけでなく失効・再発行する。外部通信: 利用者が渡す任意のURLをそのままfetchしない。許可する接続先を限定する。回数: 重い処理に利用者単位の回数制限を設け、上限に達したら停止する。データ: 個人情報の必要量、保存期間、削除手段、バックアップ・復旧方法を決める。
CORSは、本人確認ではない Origin は「接続方式・ホスト・ポート」の組み合わせです。ブラウザが異なるOriginへリクエストするとき、応答を画面側のコードから読んでよいかを制御する仕組みがCORS です。
許可するOrigin、メソッド、ヘッダーを必要な範囲に絞り、必要に応じてOPTIONSの事前確認に応答します。Cookieなどの資格情報を使うときに Access-Control-Allow-Origin: * を安易に設定しないでください。CORSで許可しなくても、ブラウザ以外からAPIを呼ぶことはできます。 認証・認可はサーバー側で必ず行います。
Cookieで認証するアプリでは、別サイトから意図しない更新操作を起こすCSRF への対策も考えます。SameSite設定、Origin確認、CSRFトークンなどを、認証方式に合わせて選びます。
キャッシュと権限を組み合わせるとき 公開してよい静的画像と、利用者別の請求書では保存方針が違います。個人用APIは Cache-Control: no-store などで共有を防ぎ、明示的なキャッシュルールがそれを上書きしないかも確認します。キャッシュキーにユーザーIDを足せば、すべての認可問題が解決するわけではありません。
管理画面を作るなら: Cloudflare Accessなどのアクセス制御も検討できます。ただし、保護していない別のURL(workers.devやプレビューなど)から同じ処理へ到達できないか、公開先全体を確認します。
公式資料:Workersの実装上の推奨事項
公式資料:Custom DomainとAccess
CHAPTER 18 実習
実習:D1に保存する小さなメモAPI
入力を受け取り、検証し、データベースに保存して一覧を返す。ここまで学んだ基本を一つにつなげます。
ローカル実習専用です。 この例にはログイン・所有者確認・回数制限を入れていません。メモを使って仕組みを学ぶためのコードです。このまま公開すると誰でも一覧を取得・追加できるため、個人情報を入れず、公開前に前章の認証・認可を追加してください。
POST /api/notestitleを送る
→ Worker形式・サイズを検証
→ D1INSERTで保存
図6:その後、GET /api/notesで最新20件を取得します。
1. 新しいWorkerとD1を準備する ターミナル:Worker only / JavaScript / デプロイNoを選ぶ
npm create cloudflare@latest -- notes-worker
cd notes-worker
npx wrangler d1 create notes-db
D1の作成コマンドはCloudflare上にデータベースを作ります。返された database_id を次の設定の指定箇所へ入れます。生成ツールが設定を追加した場合も、Binding名が DB か確認してください。
wrangler.jsonc:ファイル全体
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "notes-worker",
"main": "src/index.js",
"compatibility_date": "2026-09-17",
"d1_databases": [{
"binding": "DB",
"database_name": "notes-db",
"database_id": "作成コマンドが返したIDに置き換える"
}],
"observability": { "enabled": true }
}
2. 保存する表を作る プロジェクトの直下に schema.sql を作ります。テーブルはデータを行と列で保存する単位です。id は行を識別する番号、title はメモ本文として使う短い文字列です。
schema.sql:ファイル全体
CREATE TABLE IF NOT EXISTS notes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL
);ターミナル:ローカルDBに表を作る
npx wrangler d1 execute notes-db --local --file=./schema.sql
--localは手元のDB が対象です。Cloudflare上のD1に同じ表を作る操作とは別です。本番ではスキーマ変更をマイグレーションとして履歴管理し、適用先を確認します。
3. Workerを書く 次はファイル全体です。長い部分の多くは入力検証で、保存処理自体は最後の prepare(...).bind(...).run() です。
src/index.js:ローカル実習用のファイル全体
function json(data, status = 200) {
return Response.json(data, {
status, headers: { "Cache-Control": "no-store" }
});
}
// 本文を最大8KBまで読む。Content-Lengthだけには依存しない。
async function readSmallJson(request) {
if (!request.body) throw new Error("empty");
const reader = request.body.getReader();
const chunks = [];
let size = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
size += value.byteLength;
if (size > 8192) {
await reader.cancel();
throw new Error("too_large");
}
chunks.push(value);
}
const bytes = new Uint8Array(size);
let offset = 0;
for (const chunk of chunks) {
bytes.set(chunk, offset);
offset += chunk.byteLength;
}
return JSON.parse(new TextDecoder().decode(bytes));
}
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname !== "/api/notes") {
return json({ error: "not_found" }, 404);
}
try {
if (request.method === "GET") {
const { results } = await env.DB.prepare(
"SELECT id, title FROM notes ORDER BY id DESC LIMIT 20"
).all();
return json({ notes: results });
}
if (request.method !== "POST") {
return new Response("Method not allowed", {
status: 405, headers: { Allow: "GET, POST" }
});
}
const type = request.headers.get("Content-Type") || "";
if (type.split(";")[0].trim().toLowerCase() !== "application/json") {
return json({ error: "JSONで送ってください" }, 415);
}
let data;
try {
data = await readSmallJson(request);
} catch (error) {
return json({ error: "本文は8KB以内の正しいJSONにしてください" },
error.message === "too_large" ? 413 : 400);
}
if (typeof data?.title !== "string") {
return json({ error: "titleは文字列です" }, 400);
}
const title = data.title.trim();
if (!title || title.length > 100) {
return json({ error: "titleは1〜100文字にしてください" }, 400);
}
await env.DB.prepare("INSERT INTO notes (title) VALUES (?)")
.bind(title).run();
return json({ saved: true }, 201);
} catch {
console.error({ event: "notes_failed" });
return json({ error: "保存サービスの処理に失敗しました" }, 500);
}
}
};
? に値を渡す bind(title) は、利用者入力をSQL命令として解釈させないために使います。title.length はJavaScriptの文字列長の数え方なので、絵文字などは見た目の1文字と一致しない場合があります。
4. 保存と読み出しを確認する 一つのターミナルで起動し、別のターミナルでリクエストを送ります。curl はHTTP通信を試すコマンドです。
ターミナルA:起動
npx wrangler devターミナルB:POSTで作成 → GETで取得
curl -i http://localhost:8787/api/notes \
-H 'Content-Type: application/json' \
--data '{"title":"Workersを学ぶ"}'
curl -i http://localhost:8787/api/notes
最初は 201 と {"saved":true}、次は 200 とメモを含む一覧が期待結果です。さらに空タイトルは400、不正JSONは400、別パスは404、DELETEは405になることを試します。
ここまでできたら: 「データを保存できた」だけでなく、「不正入力では保存されない」ことも確認できています。公開する次の段階では、認証済み利用者のIDを保存し、一覧取得もその利用者のデータだけに限定します。
公式資料:D1のはじめ方
公式資料:D1のPrepared statements
CHAPTER 19 応用
実践アーキテクチャ:目的に合わせて組み合わせる
最初から全部の製品を使う必要はありません。画面、処理、保存、非同期処理を分け、必要なものだけ加えます。以下は教材用の構成例です。
A. 小さな会員制Webアプリ
ブラウザ画面を操作
→ Static Assets + Worker画面配信 / 認証 / API
→ D1:会員・メモ R2:添付ファイル
図7:R2にファイルを、D1に所有者・タイトル・ファイルキーを保存する構成例。
まずD1だけで文字データを扱い、添付機能が必要になったらR2を足します。R2のキーを知っていることと、読む権限があることは別です。ダウンロード時にWorkerで認可し、必要に応じて短期間だけ使えるURLを発行します。
B. 外部サービスからの通知を受け取る
Webhook送信元
→ Worker署名・形式の検証
→ Queue受け付けた仕事を保存
→ Consumer → D1
図8:Webhookは、イベント発生時に相手のURLへHTTP通知する仕組みです。
送信元の署名を検証し、キュー投入が完了してから受け付け成功を返します。ConsumerはイベントIDの重複を処理して、同じ通知で二重登録しないようにします。キューに入る前の受付失敗と、受け付け後の処理失敗を分けると復旧しやすくなります。
C. AIを使う問い合わせ支援
利用者の質問
→ Worker認証 / 入力量 / 利用上限
→ AI Gateway計測 / ポリシー
→ Workers AI または 外部AIプロバイダー
図9:Gatewayは任意の管理層です。WorkerからWorkers AIを直接利用する構成も可能です。
AIへの呼び出しには時間と費用がかかります。入力と出力の長さ、同時実行、利用者ごとの回数を決めます。AIの文章は事実確認済みとは限らないため、業務で使う場合は根拠の表示や人の確認を設計に含めます。保存する履歴とログには、個人情報の取り扱いも反映します。
D. 複数人で共有する部屋
複数の利用者
→ Worker参加権限を確認
→ 部屋ごとのDurable Object同じ状態を調整
図10:同じ部屋名から同じオブジェクトを選ぶことで、その部屋の処理を集約する構成例。
チャットや共同操作では、部屋ごとに一貫した状態を扱える仕組みが役立ちます。一つの巨大なオブジェクトに全利用者を集めると負荷が集中するため、部屋や対象データごとの単位を考えます。メッセージ履歴などをどこまで永続化するかも明示します。
設計時に書き出す5つの質問 誰がどのURLへ、どの操作を送るか。 誰の権限で、どのデータを読む・書くか。 その場で返す必要がある処理と、後でよい処理は何か。 同じ操作が2回来た場合や、途中で失敗した場合にどうするか。 1回あたり何を消費し、アクセス増加で何が増えるか。
CHAPTER 20 基礎
学習ロードマップと理解度チェック
一つずつ「自分で確認できる成果」を作ると、知識がつながります。日数を固定せず、達成条件を満たしてから次へ進みましょう。
段階 やること 進んでよい目安 1:Webの基礎 DNS、HTTP、CDNの図を自分の言葉で説明する。 DNSの問い合わせとWeb通信が違うと分かる。 2:最初のWorker Hello Worldを動かして文字を変える。 編集するファイルと結果を見るURLが分かる。 3:API パス、クエリ、JSON、ステータスを扱う。 正常系・400・404・405を自分で再現できる。 4:保存 D1にメモを保存する。 ローカルとリモートのDBを区別できる。 5:公開 公開してよいAPIをデプロイし、ログを見る。 公開URLでの動作とエラーを確認できる。 6:運用 認証・認可、利用上限、復旧方法を加える。 他人のデータへのアクセスを拒否できる。 7:応用 必要に応じてR2、Queues、AIなどを一つ追加する。 追加する理由と、増える費用・失敗条件を説明できる。
自分の理解を確かめる
Q1. Workersを使うには、ドメインを買う必要がある? 最初は不要です。 workers.devで始められます。独自ドメインは公開URLや運用条件に合わせて追加します。
Q2. Workerの先頭の変数に、会員のメモを保存してよい? 永続保存には使えません。 実行領域が変わったり破棄されたりするため、D1などの保存サービスを使います。
Q3. KVで同時に売れる最後の1個の在庫を管理してよい? 単純なKVの読み書きでは適しません。 結果整合性と同時更新の問題があるため、一貫した更新を扱えるデータベース設計やDurable Objectsなどを検討します。
Q4. CORSを設定すれば、APIは本人しか呼べなくなる? なりません。 CORSはブラウザからの読み取りを制御する仕組みです。サーバー側で認証・認可が必要です。
Q5. キューは必ず一度だけ届く? 重複配信される可能性があります。 同じイベントIDを何度処理しても結果が壊れない設計にします。
Q6. AI Gatewayがあれば、AIモデル自体の利用料は不要? 別に考えます。 Gatewayは呼び出しの管理層で、Workers AIや外部プロバイダーのモデル実行料金まで自動的に無料にするものではありません。
Q7. デプロイ成功だけで、アプリ完成と判断できる? まだ確認が必要です。 公開URLで正常・異常入力を試し、Bindings・権限・ログなどが正しく動くことを確認します。
次に読むテーマ 基本APIを作れたら、画面も配信するStatic Assets、ルートが増えたらルーターやフレームワーク、テストを増やすならWorkersのテスト環境へ進めます。長い複数段階の処理にはWorkflows、既存DBとの接続にはHyperdriveなどの選択肢があります。必要が生まれたときに公式資料を調べてください。
公式資料:Workers公式チュートリアル
公式資料:Workersのテスト
最初の到達点: 「受け取る → 検証する → 処理・保存する → 結果を返す」を自分で実装し、失敗時の動作も確認できること。ここまでできれば、Workersを使った小さなアプリを段階的に育てられます。
CHAPTER 21 参照
用語集:分からない言葉を引く
用語 この教材での意味
デプロイ コードや設定を実行環境へ配置すること。 ランタイム プログラムを実行する環境。 エッジ 利用者に近い側のネットワーク拠点を指す言葉。実行場所の保証とは別。 オリジン 元のコンテンツや応答を提供するサーバー。文脈によりOriginはURLの接続方式・ホスト・ポートの組み合わせも指す。 エンドポイント APIなどにアクセスする特定のURLや接続先。 ハンドラー イベントが来たときに呼び出される処理。 バインディング 設定名とサービスや値を結び、コードから利用可能にする仕組み。 永続化 実行中のメモリが消えた後も残る場所にデータを保存すること。 整合性 複数の読み書きでデータがどう見えるかという性質。 結果整合性 更新が直ちに全読取先へ反映されるとは限らず、時間とともに整合する性質。 冪等性(べきとうせい) 同じ操作を繰り返しても、意図した最終結果が変わらない性質。 スキーマ / マイグレーション データの表などの構造 / その構造の変更を履歴として管理・適用すること。 ストリーム 全体を一度に保持せず、データを少しずつ受け渡す方式。 Webhook イベントが起きたとき、指定URLへHTTPで通知する仕組み。 Observability ログや指標などから、実行中のシステムの状態を把握するための機能。 TTL キャッシュなどが有効な期間。 レート制限 一定の時間内に許可する回数などの制限。 シークレット APIキーなどの機密設定値。
公式資料の使い方 各章末のリンクはCloudflare・AWS・Google Cloudの公式ドキュメントです。料金・上限・設定方法は、使う直前にそのページを確認してください。ページの更新日、対象プラン、実験的機能かどうかも読みます。本文の構成図と練習問題は、この教材のために作成したものです。
教材確認日:2026年9月17日。製品の仕様やUIは変わります。学習用コードの検証範囲は巻末の「確認済みの範囲」に記載しています。本教材はCloudflare公式の発行物ではありません。