Hanami(Ruby製Webフレームワーク)徹底解説:1系/2系の違い・ROM/dry-rb活用・Rails比較と導入・移行ポイント

Hanami とは:概要と位置づけ

Hanami(ハナミ)は、Ruby製のWebフレームワークで、設計の明確さ・モジュール性・軽量性を重視したフレームワークです。かつては「Lotus」という名前で開発されていましたが、後に Hanami に改名され、現在は公式ドキュメントとコミュニティで Hanami として運用されています。Rails と同じく「フルスタックに使える」部分を持ちながらも、コンポーネントの分離や不変性(immutability)、依存関係の明示的管理など、よりモダンで堅牢なアーキテクチャ原則を打ち出しているのが特徴です。

設計哲学(なぜ Hanami を選ぶのか)

  • 明確な責務分離:MVC 的な概念に加え、エンティティ、リポジトリ、アクション(コントローラ相当)、ビュー/テンプレートなどを明確に分離します。ビジネスロジックをドメイン層に閉じ込め、プレゼンテーションや永続化から切り離します。

  • 小さなメモリフットプリント:Rails に比べてプロセスあたりのメモリ消費を抑える設計が意識されています(特に Hanami 1 系の頃からの主張)。軽量なアプリケーションやマイクロサービス的な利用に向きます。

  • モジュール性とスライス(Slices):アプリケーションを自己完結した小さなモジュールに分割でき、チームでの分担や境界の明確化に役立ちます(Hanami 2 系でより強化)。

  • 外部ライブラリとの連携:データ層に ROM(rom-rb)や dry-rb 系ライブラリを採用できるなど、柔軟に選択肢を持てる設計です。

歴史的背景(簡潔に)

Hanami は元々 Lotus という名前で始まり、Ruby コミュニティにおける「Rails 以外の選択肢」として注目を集めました。プロジェクトはコミュニティ主導で成長し、命名変更やアーキテクチャの見直しを経て、よりモジュール化・拡張性を高める方向へ進化しています。現在は Hanami 1 系(従来の実装)と Hanami 2 系(設計を大幅に見直した新版)が存在し、それぞれ思想や実装に違いがあります。

コアコンポーネントと主要概念

Hanami の理解で重要な要素を挙げます。

  • アプリケーション(app):Hanami プロジェクトは複数のアプリケーションを含めることができます(Web アプリ、API、admin 用アプリなど)。

  • アクション(Action):コントローラに相当する「アクション」は、1 リクエスト=1 オブジェクトという設計が推奨されます。副作用を最小にし、テストしやすくするためのシンプルな構造です。

  • ビュー/テンプレート:プレゼンテーションはビューオブジェクトとテンプレート(ERB や他テンプレートエンジン)で構成され、ロジックは最小に保たれます。

  • エンティティ(Entity):ドメインオブジェクト。ビジネスロジックを担う中心です(不変性や値オブジェクトの利用を奨励)。

  • リポジトリ(Repository):データアクセスの抽象レイヤー。ORM に依存せず、ROM などを利用して永続化を行います。

  • スライス(Slice):アプリケーション内の完全に独立したサブアプリケーション(Hanami 2 の概念)。チーム分割や境界設計に便利です。

データ層:ROM と dry-rb の活用

Hanami は ActiveRecord に限定されない設計で、ROM(Ruby Object Mapper)などのライブラリと組み合わせることが推奨されます。ROM はリポジトリパターンに近い形でデータの抽象化を提供し、SQL や NoSQL など複数のデータソースを同一の概念で扱いやすくします。また、dry-rb 系の dry-types や dry-validation を使うことで、型付けやバリデーションを堅牢に実装することが可能です。

Hanami 1 系と 2 系の違い(概要)

Hanami はメジャーバージョンで設計の見直しが行われています。ここでは代表的な違いを挙げます(詳細はバージョンのドキュメントを参照してください)。

  • アーキテクチャの再設計:Hanami 2 はよりモジュール志向で、アプリケーションの分離(スライス)や DI(依存性注入)のサポートが強化されています。

  • ルーティングやミドルウェアの整理:ルーターやミドルウェア周りが再設計され、より明示的で理解しやすくなっています。

  • 互換性:Hanami 2 は API レベルで互換性がない(あるいは限定的)箇所があるため、1 系からの移行には設計上の見直しが必要になることがあります。

ルーティングとアクションの特徴

Hanami のルーティングはシンプルかつ明示的です。各ルートは対応するアクション(オブジェクト)に結び付けられ、アクションは一貫してリクエストを処理します。これにより、各アクションが独立性を保ち、テストやリファクタリングが容易になる利点があります。また、Rack ミドルウェアとの親和性も高く、標準的な Rack ミドルウェアをそのまま利用できます。

テストと開発ワークフロー

Hanami は設計が明確なため、ユニットテストや単体テストを書きやすくなっています。アクション単位、リポジトリ単位でのテストが自然に分離されるため、モックやスタブの境界を決めやすいのが特徴です。RSpec や Minitest との互換性があり、好みのテストフレームワークを選べます。

パフォーマンスと運用面(実運用の観点)

Hanami は軽量性を重視するため、メモリ使用量や起動時間が比較的抑えられます。マイクロサービスや小〜中規模の Web サービスで高い効率を発揮します。ただし、実際のパフォーマンスはアプリケーションの設計・クエリの最適化・ミドルウェア構成などに依存します。運用面では Rack ベースであるため、既存の Rack 対応サーバ(Puma, Unicorn など)やコンテナベースのデプロイと親和性があります。

Rails との比較(いつ Hanami が向いているか)

Rails は「規約より設定(convention)」で迅速な開発を助ける一方、アプリが大規模化すると密結合や肥大化が問題になることがあります。Hanami は以下のケースで有利です。

  • 明確なレイヤー分離で保守性を高めたい場合

  • 軽量なプロセスでメモリ使用量を抑えたい場合

  • 複数の小さなサブアプリケーション(スライス)に分けて開発したい場合

  • データアクセスを明確に抽象化(ROM など)して、DB 技術を切り替える可能性がある場合

逆に、Rails のエコシステム(大量のジェム、ジェネレータ、広範なドキュメント)や「習熟したチームで短期間に開発する」ことを重視するなら Rails の方が生産性が高い場面もあります。

移行や学習のポイント

既存の Rails プロジェクトから Hanami に移行する場合、単純なリプレースではなく設計の再考が必要です。特にドメイン層の分離、リポジトリパターンの導入、アクションベースのコントローラ設計などを意識して段階的にリファクタリングすることが現実的です。学習面では以下が重要です。

  • Hanami のディレクトリ構造とコンポーネントの責務を理解する

  • ROM や dry-rb 系の基本思想(スキーマ、型、バリデーション)に慣れる

  • スライスや依存注入のパターンを学び、設計に組み込む

エコシステムとコミュニティ

Hanami は Rails ほど巨大なエコシステムではありませんが、公式ドキュメントや GitHub、コミュニティによるプラグインやサンプルが存在します。主要な外部ライブラリ(ROM、dry-rb)との連携が進んでいるため、堅牢な基盤を持ちながらも選択と組み合わせで柔軟に拡張できます。導入前に公式ドキュメントや GitHub の issue、実際のプロジェクト事例をチェックすることをおすすめします。

導入手順(簡易ガイド)

  • 公式ドキュメントを参照してプロジェクトを作成:hanami new など(バージョンによりコマンドは異なるため公式ガイドを確認)。

  • アプリの構成を設計:サブアプリ(API/Admin)構成、スライスの分割など。

  • データ層の選定:ROM を使うか、別のライブラリを使うか決定。

  • CI/テスト環境の構築:RSpec や Minitest、さらにはコンテナ化や自動デプロイの整備。

実際の採用を検討する際のチェックリスト

  • チームにとって「明確なレイヤー分離」はメリットか?

  • メモリや起動時間に制約はあるか?(軽量性のメリットを活かせるか)

  • ROM や dry-rb を受け入れる用意はあるか?既存の ORM(ActiveRecord)からの移行労力は許容できるか?

  • コミュニティサポートや導入事例をどの程度重視するか(Rails と比べた調達性)

まとめと今後の展望

Hanami は「設計の明瞭さ」と「モジュール性」を重視する Ruby 製 Web フレームワークです。Rails のような巨大なエコシステムを前提にしない分、必要な機能を選んで組み合わせられる柔軟さがあり、特に中〜大規模化した際の保守性向上やマイクロサービス的な構成に向いています。Hanami 1 系と 2 系で思想や実装に差があるため、導入時はバージョンの違いと移行コストを確認し、公式ドキュメントとコミュニティ情報を参照することが重要です。

参考文献