Hono × Cloudflare WorkersでJSON APIを作る手順

※本記事にはプロモーション(広告・アフィリエイトリンク)を含みます。
Cloudflare Workers でバックエンド API を作りたいが、どのフレームワークを使えばいいか迷っている——そういう方に向けて、軽量フレームワーク Hono を使った JSON API の作り方を手順ごとに書きます。環境構築からデプロイまで、コマンドと設定値をそのまま使える形で整理しました。
Hono を選ぶ理由
Hono は Cloudflare Workers・Deno・Bun・Node.js など複数のランタイムで動く軽量 Web フレームワークです。Express のような Node.js 独自のオブジェクトではなく、Web 標準の Request / Response をベースに設計されているため、Workers 環境との相性が良いです。
主な特徴を挙げます。
- ルーティングが高速:独自の高速ルーター実装を採用しており、多数のルートを登録しても処理速度が低下しにくい設計です
- ミドルウェアが内蔵:CORS・認証・ロガーなどが標準パッケージに含まれており、追加インストールなしで使えます
- 型安全:TypeScript 対応で
c.req.json<T>()のように型パラメータを渡せます
Express に慣れた方であれば、ほぼ同じ書き方で移行できます。
事前準備
必要なもの:
- Node.js 18 以上(
node -vで確認) - Cloudflare アカウント(無料プランで動作確認できます)
Wrangler CLI はプロジェクト作成時に自動でインストールされますが、先に認証を済ませておくと後の手順がスムーズです。
npm install -g wrangler
wrangler login
wrangler login を実行するとブラウザが開き、Cloudflare アカウントへの OAuth 認証が求められます。
プロジェクトを作成する
Hono の公式テンプレートを使うと、Workers 向けの設定済みプロジェクトがすぐに生成されます。
npm create hono@latest my-api
対話式のプロンプトが起動します。テンプレートの選択肢が複数表示されますが、cloudflare-workers を選んでください。
? Which template do you want to use?
aws-lambda
bun
❯ cloudflare-workers
deno
nodejs
インストール後:
cd my-api
npm install
生成されるファイル構成は次のとおりです。
my-api/
├── src/
│ └── index.ts # エントリーポイント
├── wrangler.toml # Workers 設定ファイル
├── tsconfig.json
└── package.json
ルーティングと JSON レスポンスを書く
src/index.ts を開くと、最小構成の Hono アプリがすでに書かれています。ここにエンドポイントを追加します。
import { Hono } from 'hono'
const app = new Hono()
// GET / — テキストレスポンス
app.get('/', (c) => c.text('Hello Hono!'))
// GET /api/items — JSON を返す
app.get('/api/items', (c) => {
const items = [
{ id: 1, name: 'りんご' },
{ id: 2, name: 'みかん' },
]
return c.json({ items })
})
// GET /api/items/:id — パスパラメーターを受け取る
app.get('/api/items/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, name: 'サンプル' })
})
// POST /api/items — リクエストボディを受け取る
app.post('/api/items', async (c) => {
const body = await c.req.json<{ name: string }>()
return c.json({ created: body.name }, 201)
})
// 存在しないルートへの 404
app.notFound((c) => c.json({ error: 'Not Found' }, 404))
export default app
いくつかポイントを補足します。
c.json(data, statusCode)で JSON レスポンスを返します。ステータスコードを省略すると 200 になりますc.req.param('id')でパスパラメーターを取得できますc.req.json<T>()でリクエストボディを JSON としてパースします。ボディが有効な JSON 形式でない場合はパースエラーになりますexport default appが必須です。Workers はデフォルトエクスポートをfetchハンドラとして扱います
ローカル確認と CORS 設定
npm run dev でローカルサーバーが起動します。
npm run dev
# → http://localhost:8787 で確認できます
別ターミナルで curl を叩いて動作を確認します。
curl http://localhost:8787/api/items
# → {"items":[{"id":1,"name":"りんご"},{"id":2,"name":"みかん"}]}
curl -X POST http://localhost:8787/api/items \
-H "Content-Type: application/json" \
-d '{"name":"ぶどう"}'
# → {"created":"ぶどう"}
フロントエンドから API を叩く場合は CORS の設定が必要です。Hono は CORS ミドルウェアを内蔵しています。
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
const app = new Hono()
// 全ルートにリクエストログを出力
app.use('*', logger())
// /api/* にだけ CORS を適用
app.use('/api/*', cors({
origin: ['https://example.com', 'http://localhost:3000'],
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
}))
// ...ルート定義
export default app
origin に '*' を渡すと全オリジンを許可しますが、本番では発信元ドメインを明示するほうが安全です。allowMethods に指定しないメソッドへのプリフライトリクエストには適切な CORS ヘッダーが返されず、ブラウザ側でブロックされます。
wrangler.toml の設定とデプロイ
wrangler.toml は Workers 全体の設定ファイルです。テンプレートで自動生成されますが、確認しておくべき項目があります。
name = "my-api"
main = "src/index.ts"
compatibility_date = "2025-01-01" # 執筆時点の例。最新の推奨値は公式ドキュメントで確認してください
# 環境変数(値をそのまま書く。シークレットは wrangler secret put で別途設定)
[vars]
ENVIRONMENT = "production"
# KV Namespace を使う場合の例
# [[kv_namespaces]]
# binding = "MY_KV"
# id = "xxxxxx"
# D1 データベースを使う場合の例
# [[d1_databases]]
# binding = "DB"
# database_name = "my-db"
# database_id = "xxxxxx"
compatibility_date は Workers API の互換性バージョンを指定します。古い日付のままにすると最新の API が使えないことがあるため、新規プロジェクトではなるべく新しい日付を使います。
シークレット(API キーなど機密情報)はファイルに書かず、wrangler secret put で登録します。
wrangler secret put MY_SECRET
# 対話式でシークレット値を入力できます
デプロイは 1 コマンドです。
wrangler deploy
成功すると https://my-api.<accountname>.workers.dev のような URL が発行されます。カスタムドメインを使いたい場合は Cloudflare ダッシュボードの Workers 設定から追加できます。
よく使うコマンドをまとめます。
| 操作 | コマンド |
|---|---|
| ローカル起動 | npm run dev |
| 本番デプロイ | wrangler deploy |
| リアルタイムログ確認 | wrangler tail |
| シークレット登録 | wrangler secret put SECRET_NAME |
静的フロントエンドを Cloudflare Pages で配信して、この Workers API と組み合わせる構成もよく使われます。Pages のデプロイ手順は Cloudflare Pagesに静的サイトを無料でデプロイする手順 にまとめています。
まとめ
Hono + Cloudflare Workers で JSON API を作る手順を整理します。
wrangler loginで Cloudflare に認証するnpm create hono@latestでプロジェクトを生成し、cloudflare-workersテンプレートを選ぶsrc/index.tsにルートを書くnpm run devでローカル確認するwrangler deployでエッジにデプロイする
次のステップとして、D1(Cloudflare のマネージドな SQLite 互換データベース)を Binding として繋ぐと、Workers だけでデータの読み書きまで完結する API を作れます。まずは wrangler deploy まで動かし、自分のユースケースに合わせて拡張していくのがおすすめです。
よくある質問
Cloudflare Workersの無料枠はどのくらいですか?
公式ドキュメントによると、無料プランでは1日あたり10万リクエスト、CPU時間は1リクエストあたり10msが上限です(執筆時点)。個人の検証や小規模なAPIであれば無料枠で動かせます。大量トラフィックには有料のWorkers Paidプランの検討が必要です。
HonoはCloudflare Workers以外のランタイムでも使えますか?
はい、HonoはCloudflare WorkersのほかにDeno・Bun・Node.js・Fastly Computeでも動作します。Web標準のRequest/Responseをベースに設計されているため、ランタイムを切り替えてもコードの大部分を再利用できます。
wrangler devでローカル起動すると本番と同じ挙動になりますか?
ほぼ同等ですが完全同一ではありません。KVやD1のローカルシミュレーションはwranglerが提供しますが、一部の挙動や制限値は本番Workers環境と異なる場合があります。最終確認はwrangler deploy後の本番環境で行うことを推奨します。