Gemcook Tech Blog
🔥

Honoのルーティングってどんなルーターがあるの?

2024/12/24に公開

この記事は Hono Advent Calendar 2024 の 24 日目の記事です。

https://qiita.com/advent-calendar/2024/hono

こんにちは、株式会社 Gemcook でバックエンドエンジニアをしているあさひです!Hono のルーティングについて意識したことがなかったので改めて調べて記事にしてみました!

Hono とは?

Hono は、Cloudflare Workers、Deno、Bun など、様々な JavaScript ランタイムで動作する、Web 標準準拠の超高速で軽量な Web フレームワークです。シンプルな記述と使いやすさや開発スピード上げやすいことが個人的には推しポイントです。間違いなく 2024 年の TypeScript のフレームワークで TS 界隈を盛り上げたフレームワークの一つだと思います。

なぜ速いのか?

Hono は、公式ページのトップでも以下のようにあります。Hono のいい点でもありますが、なぜ高速にルーティングできるのかやどのように動作しているかを気にしなくていいという点があると思っています。ただそもそもなんでこんなに速いのか?ということが気になったのでどんなルーターがあるのか調べてみようと思います。

Fast, lightweight, built on Web Standards. Support for any JavaScript runtime.

https://hono.dev/

Hono で選べるルーター

RegExpRouter

RegExpRouter は JavaScript の世界で最も高速なルーターらしいです。

似たようなものにpath-to-regexp を用いた Express があり線形ループを使用しています。都合上 Express にある正規表現を使ったルーターはすべてのルートに対して正規表現のマッチングが実行されるのでルートが増えるにつれてパフォーマンスが低下するデメリットがあるようです。

一方で Hono の RegExpRouter はルートパターンを「1 つの大きな正規表現」に変換するため 1 回のマッチングでルーティングの結果を取得できるらしくツリーベースのアルゴリズムを使用するルータよりも高速に動作するようです。Perl で同じ正規表現を使用した戦略でパフォーマンス向上を行なっている実績のあるモジュールがあるようです。

https://github.com/honojs/hono/pull/109

TrieRouter

TrieRouter は、Trie ツリー アルゴリズムを使用するルーターで RegExpRouter と同様に線形ループを使用していないルーターです。RegExpRouter が登場するまではおそらく TrieRouter がデフォルトだったルーターです。RegExpRouter ほど高速ではないものの Express のルーターよりは高速に動作していてすべてのパターンをサポートしているものの正規表現を用いた RegExpRouter はサポートしていません。

SmartRouter

さてここまでで RegExpRouter と TrieRouter については書きましたが、良し悪しはありそうで、RegExpRouter は超高速だがすべてのルーティング パターンをサポートしていない、TrieRouter は最速でないものの全てのパターンをサポートしています。この 2 つのルーターのいいとこどりをしようと言うのが SmartRouter です。

SmartRouter は登録されたルーターから推測して最適なルーターを選択してくれるルーターです。Hono はデフォルトで SmartRouter が採用されており、RegExpRouter と TrieRouter で適切なものを選択してくれます。

https://github.com/honojs/hono/blob/4eb101dd03e66e20dfda86e6e5ebce8045d61d05/src/hono.ts#L16-L34

LinearRouter

さてここまででじゃあルーターは全部網羅したねと思うかもしれません。ただ RegExpRouter は高速なもののルート登録フェーズが遅くなる可能性があります。そのためリクエストごとに初期化する環境には適していないという特徴があります。(大きい正規表現を使うからかな?)LinearRouter は、線形アプローチを使用して文字列をコンパイルせずにルートを追加するため、ルート登録は RegExpRouter よりも大幅に高速になる特徴があります。Fastly Compute のような環境ではプリセット付きの LinearRouter を使用する方が適切になってきます。

PatternRouter

PatternRouter は Hono のルーターの中で最も小さいルーターです。そもそも Hono はかなりサイズが小さいのですが、リソースが限られた環境のためにさらに小さくする必要がある場合は PatternRouter が適切です。

[WIP]FilePatternRouter

FilePatternRouter はファイルベースのルーティング用のルーターのようです。原理としては RegExpRouter とほぼ同じ原理で動作していると言うことらしく RegExpRouter とほぼ同じパフォーマンスかつ初期化のパフォーマンスも LinearRouter とまではいかないものの十分に高速なルーターのようです。

ただまだマージされておらず、以下のようにコメントされています。v4 系でリリース予定となっていますがどうなんですかね?

Currently, for my plan to release the file-based routing feature, I'm not sure if it will be Sonik, separate from this Hono repo, or another framework structure, but it will be released as v4. So, I think we should consider including this FilePatternRouter in v4. Until then, how about we keep this open?

https://github.com/honojs/hono/pull/1805

まとめ

普段特にルーターを選択して使うという利用をしていなかったので、おそらく SmartRouter を使用していたと言うことが理解できました。あとは中々普段意識せずに使える Hono の良さを享受していた部分かなとも思うので改めて調べてみて勉強になりました!

結局調べてみてどれを使えばいいんだと自分自身思ったのですがさすが作者の@yusukebeさんですね。しっかりまとめてくれていましたので、以下を参照していただくといいのかと思います。プリセットでルーターが切り替わるように初めから用意してくれているようです。

https://zenn.dev/yusukebe/articles/ee57dc12f34724#プリセットという概念と実装

さて本当は Hono を使って作った何かしらの紹介でもできたらよかったのですが中々手につかなくて叶わず… 来年こそは OSS 活動も頑張るつもりなのでコントリビュートに限らずなにかしらで貢献できればと考えています!

Gemcook Tech Blog
Gemcook Tech Blog

Discussion