Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Honoとエッジランタイム

💡 NotebookLM で解説を聞く

Web開発のフレームワークの世界で、最近注目を集めているHono(炎)について学んでいきましょう。 Honoにはエッジランタイムにぴったりな特徴があります。

この記事で学べること

  • なぜユーザーに近い場所 (エッジ) でコードを動かすことが重要なのか理解する
  • Honoがどのようにその課題を解決するのか理解する

通信の物理的限界: 光の速さでも遅い?

あなたが東京にいて、アメリカ・オレゴン州にあるサーバーにアクセスするとします。

直線距離は約8,000km。光の速度は約300,000km/s。単純計算で片道約27ミリ秒、往復で約 54ミリ秒 かかります。

「たった54ミリ秒?」と思うかもしれませんが、これは理論上の限界値です。実際には、ケーブルが直線ではなかったり、サーバーでの処理時間があったり、ルーターを経由したりするので、100〜200ミリ秒以上かかることは珍しくありません。

なぜこれが問題なのか

Webアプリケーションでは、1回のページ表示で何十回もサーバーとの通信が発生します。

  • HTMLの取得
  • CSSの取得
  • JavaScriptの取得
  • APIからデータの取得(複数回)
  • 画像の取得(複数枚)

仮に1回の通信に150ミリ秒かかるとして、20回通信すれば3秒。ユーザーは「遅い」と感じ始めます。

Note: 実際に GCPing で遅延を測定してみましょう。あわせて、海底ケーブルがどのように地球上に張り巡らされているか Submarine Cable Map と見比べてみましょう。

解決策: ユーザーの近くでコードを動かす

エッジコンピューティングとは

「エッジ(端)」とは、ネットワークの端、つまりユーザーに近い場所のことです。

【従来のアーキテクチャ】
ユーザー(東京) ──→ 太平洋を横断 ──→ サーバー(米国)
                                         ↓
ユーザー(東京) ←── 太平洋を横断 ←── レスポンス

       往復で100〜200ms以上

【エッジコンピューティング】
ユーザー(東京) ──→ エッジサーバー(東京) ──→ レスポンス

       往復で10〜30ms程度

世界中にサーバーを分散配置し、ユーザーに最も近いサーバーが処理を担当する。これがエッジコンピューティングの基本的な考え方です。

エッジランタイムとは

エッジコンピューティングを実現するための実行環境を「エッジランタイム」と呼びます。

代表的なエッジランタイム:

  • Cloudflare Workers - 世界300都市以上にサーバーを持つ
  • Deno Deploy - Deno社が提供するエッジランタイム
  • Vercel Edge Functions - Next.jsで有名なVercelのエッジランタイム

エッジランタイムのメリット

メリット説明
低遅延ユーザーに近い場所で処理するため、体感速度が大幅に向上
従量課金使った分だけ支払う。小規模なら月額無料枠で収まることも
自動スケーリングアクセスが増えても自動で対応。サーバー管理が不要

Note
光の速さを超える通信のためのプロトコル

2024年 4月1日エイプリルフール に「Faster Than Light Speed Protocol光の速さを超える通信のためのプロトコル [RFC 9564]」仕様が公開されました。 このRFCのプロトコルは文字通り「光の速さを超える通信」を可能とするための技術ですが、実装は「まだ」存在しません 😃

エッジランタイムのトレードオフ

エッジランタイムは魅力的な技術ですが銀の弾丸ではありません。トレードオフを理解して適材適所で使うことが重要です。

デバッグの難しさ

世界中に分散されたサーバーで動くため、問題の特定が難しくなることがあります。

ローカル環境 → 動作する ✅
東京のエッジサーバー → 動作する ✅
ロンドンのエッジサーバー → なぜか動かない ❌

特定の地域でのみ発生するバグは、その地域のネットワーク環境やサーバー設定が原因の可能性があり、デバッグが複雑になります。

そのため、ローカル環境でもエッジランタイムでも同じコードがどこでも動く、Web標準APIを活用したフレームワークが重要です。

データの一貫性の課題

世界中のサーバーにデータを分散させる場合、結果整合性という概念を理解する必要があります。

【例: SNSの「いいね」機能】
1. 東京に住んでいるAさんが投稿に「いいね」 → 東京のサーバーに記録
2. ロンドンに住んでいるBさんがその投稿を見る
3. データ同期に時間がかかるため、Bさんには「いいね」が反映されていない
4. 数秒後、データが同期され、Bさんにも「いいね」が表示される

このような「少しの遅れ」を許容して、結果的にデータが一致すれば良い、という設計が、「結果整合性」の考え方です。

実行環境の制約

エッジランタイムは従来のサーバーと比べて、制約があることが多いです。

制約説明
実行時間の制限1リクエストあたり数秒〜数十秒の制限がある
メモリの制限使用できるメモリが限られている
ファイルシステム永続的なファイル保存ができない(一時的なメモリストレージのみ)
利用可能なライブラリNode.js標準ライブラリの一部が使えない場合がある

いつエッジランタイムを選ぶべきか

エッジランタイムが向いているケース:

  • 低遅延が重要なケース (チャット、ゲーム、リアルタイム通知など)
  • 世界中のユーザーを対象とするアプリケーション (SNS、動画配信など)
  • 読み取り中心のAPI (ニュースサイト、ブログ、商品カタログなど)

従来サーバーが向いているケース:

  • 長時間の処理が必要なケース (動画エンコード、大量のバッチ処理など)
  • 大量のデータを扱うアプリケーション (ビッグデータ分析、機械学習モデルのトレーニングなど)
  • 厳密なデータ一貫性が必要なAPI (金融取引、在庫管理など)

エッジランタイムのメリットとトレードオフを理解した上で、適切な技術選択をすることが大切です。そして「エッジランタイム」で最大限のパフォーマンスを発揮できるように設計されたフレームワークが「Hono」なのです。

Honoとは何か

Hono(炎)は、TypeScriptで書かれた軽量・高速なWebフレームワークです。

import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => c.text("Hello Hono!"));

export default app;

たったこれだけでWebサーバーが完成します。

Honoの特徴

  • 爆速 🚀 - RegExpRouter 速い。逐次処理を用いない。まじ速い。
  • 軽量 🪶 - hono/tiny プリセットはわずか 14kB 未満。依存関係ゼロでWeb標準のみ。
  • マルチランタイム 🌍 - Cloudflare Workers、Fastly Compute、Deno、Bun、AWS Lambda、Node.js。どこのプラットフォームでも同じコードが動く。
  • バッテリー同梱Batteries Included 🔋 - 内蔵のミドルウェア、カスタムミドルウェア、サードパーティのミドルウェア、ヘルパー。いわゆる バッテリー同梱Batteries Included
  • 楽しい開発体験 😃 - 超クリーンAPI。TypeScriptが第一級対応。すぐ“型“付く。

Features

  • Ultrafast 🚀 - The router RegExpRouter is really fast. Not using linear loops. Fast.
  • Lightweight 🪶 - The hono/tiny preset is under 14kB. Hono has zero dependencies and uses only the Web Standards.
  • Multi-runtime 🌍 - Works on Cloudflare Workers, Fastly Compute, Deno, Bun, AWS Lambda, or Node.js. The same code runs on all platforms.
  • Batteries Included 🔋 - Hono has built-in middleware, custom middleware, third-party middleware, and helpers. Batteries included.
  • Delightful DX 😃 - Super clean APIs. First-class TypeScript support. Now, we’ve got “Types”.

引用元: https://hono.dev/docs/#features

なぜ「マルチランタイム」が重要なのか

従来、エッジランタイムごとに異なる書き方が必要でした。

// Cloudflare Workers用
export default { fetch(req, env) { ... } }

// Deno用
Deno.serve((req) => { ... });

// Node.js用
import http from "node:http";
http.createServer((req, res) => { ... });

Honoを使えば、どの環境でも同じコードが動きます

// どの環境でもこのコードでOK
import { Hono } from "hono";
const app = new Hono();
app.get("/", (c) => c.text("Hello!"));
export default app;

これにより、開発環境はNode.js、本番環境はCloudflare Workers、という構成も簡単に実現できます。

Honoを使った実践例

例1: シンプルなAPIサーバー

import { Hono } from "hono";

const app = new Hono();

// ユーザー一覧を返すAPI
app.get("/api/users", (c) => {
  return c.json([
    { id: 1, name: "田中太郎" },
    { id: 2, name: "山田花子" },
  ]);
});

// 特定のユーザーを返すAPI
app.get("/api/users/:id", (c) => {
  const id = c.req.param("id"); // URLパラメータを取得
  return c.json({ id, name: "田中太郎" });
});

export default app;

例2: ミドルウェアの活用

ミドルウェアとは、リクエストを処理する「途中の処理」のことです。

import { Hono } from "hono";
import { logger } from "hono/logger"; // ログ出力
import { cors } from "hono/cors"; // CORS対応
import { basicAuth } from "hono/basic-auth"; // Basic認証

const app = new Hono();

// 全リクエストにログを出力
app.use("*", logger());

// /api/* へのリクエストにCORSを許可
app.use("/api/*", cors());

// /admin/* へのリクエストにBasic認証を要求
app.use(
  "/admin/*",
  basicAuth({
    username: "admin",
    password: "secret",
  }),
);

app.get("/api/public", (c) => c.text("誰でもアクセス可能"));
app.get("/admin/dashboard", (c) => c.text("管理者のみアクセス可能"));

export default app;

ポイント

概念説明
エッジコンピューティングユーザーに近い場所でアプリを実行し、遅延を減らす考え方
エッジランタイムエッジでアプリを動かすための実行環境(Cloudflare Workers等)
Hono軽量・高速・マルチランタイム対応のWebフレームワーク

参考文献