Hanami
强调模块化、显式依赖和长期可维护性的现代 Ruby 全栈 Web 框架。
项目概述
Hanami 将 Router、Action、View、数据库、资源、邮件和国际化等单一职责组件组合成完整框架,并通过容器、依赖注入与 Slice 帮助大型 Ruby 应用保持清晰边界。
Hanami 是采用 MIT 许可证的 Ruby 全栈 Web 框架,目标是让应用在持续增长时仍保持清晰、模块化和易于测试。Hanami 3 将 Rack 路由、独立 Action、View 与模板、基于 ROM 和 Sequel 的数据库层、esbuild 资源构建、Mailer、国际化和结构化日志整合在一起。应用代码会自动注册到依赖容器,并可通过 Deps 显式注入;业务较大时还能用 Slice 划分领域边界、独立启动组件。它既能构建服务端渲染网站,也适合 JSON API、后台服务和模块化单体应用。
主要特点
Hanami 用小型、可组合的对象构建完整 Web 应用,并把依赖、输入、持久化和表现层边界明确表达在代码中。
独立 Action
每个 HTTP 端点由单独的 Action 类处理 request 与 response,参数验证、状态码、重定向和异常处理边界清晰。
容器与依赖注入
app 下的组件会自动注册到容器,Deps mixin 以显式键注入 Repo、Mailer、客户端和设置,使对象更容易替换与单元测试。
Slice 模块边界
可按 Billing、Admin 或 API 等领域拆分 Slice;每个 Slice 拥有独立容器、设置、Provider 和 Action,并能控制组件导入导出。
View 与表现层
View 类通过 Exposure 准备模板数据,Context、Part、Helper 和 Partial 组织表现逻辑,默认使用 ERB 并支持 Tilt 引擎。
ROM 数据库层
Relation 描述 Schema、关联和可组合查询,Repo 提供稳定的领域接口,Struct 表达不可变结果,并通过 Sequel 管理 SQL 和迁移。
Operation 业务流程
基于 dry-operation 的 Operation 可把验证、持久化和通知等步骤串成显式流程,并在失败时短路,避免业务逻辑散落在 Action。
Mailer 与国际化
Hanami 3 集成可注入、可测试的 Mailer,并提供应用级国际化,让邮件模板、翻译和本地化遵循同一组件模型。
现代资源与可观测性
官方资源构建器基于 esbuild,也允许替换其他 Bundler;结构化日志、设置类型和 Provider 便于生产集成与诊断。
适用场景
适合希望使用 Ruby 构建长期业务系统,同时重视模块边界、可替换依赖和独立测试能力的团队。
中大型业务系统
清晰的组件职责、依赖注入和 Slice 适合需要多年迭代的 SaaS、运营平台和企业内部应用。
模块化单体
团队可以按业务领域划分 Slice,在一个部署单元内获得明确边界,并为未来拆分服务保留空间。
JSON API 与后端服务
Rack Router、独立 Action、参数验证和 Relation/Repo 适合构建 REST API、移动端后端和内部服务。
服务端渲染网站
View、ERB、Layout、Part、资源构建和国际化可完成内容丰富、渐进增强的传统 Web 应用。
后台任务与业务流程
Operation、容器和 Provider 能让同一套业务组件用于 HTTP、任务队列、定时任务与命令行入口。
重视测试的 Ruby 项目
小型 Action、可注入依赖、纯业务对象和内存邮件交付适合快速、细粒度的 RSpec 或 Minitest 测试。
优点与注意事项
技术选型不仅要看能力,也要理解它带来的团队成本。
主要优点
Hanami 擅长的地方
- 组件职责明确,Action、View、Operation 和 Repo 不必共享隐式上下文
- 依赖容器与 Deps 让替换第三方客户端和编写单元测试更直接
- Slice 能在模块化单体中建立清晰的领域与加载边界
- ROM Relation 和 Repo 将查询细节与业务接口分离
- Mailer、国际化、资源和日志已覆盖现代全栈应用的关键能力
- 遵循 Rack 生态,可使用 Puma、中间件和常见 Ruby 部署平台
需要注意
采用前应考虑的问题
Gem、教程、脚手架、托管范例和招聘市场都更小;认证、管理后台等常见能力可能需要自行组合和维护。
Container、Provider、Slice、Relation、Repo、Operation 与 View Exposure 对传统 Active Record 或 Rails 用户有明显学习成本。
Hanami 较少依赖全局约定,团队需要决定组件职责、Slice 边界和跨领域依赖;过早拆分也会造成额外结构。
数据由 Relation 查询、Repo 封装并映射为 Struct,而非带持久化行为的 Model;迁移团队应先用真实查询验证理解。
完整 HTML 应用通常同时需要 Ruby 与 Node.js,用 Bundler 和 npm 锁定依赖,并在 CI 中构建资源。
Hanami 3 要求 Ruby 3.3,并调整了 Action、Mailer、国际化和部分默认行为;从 2.3 升级时应逐项阅读升级说明。
快速开始
创建 Hanami 3 应用,定义路由与独立 Action,连接数据库 Relation 和 Repo,再用 View 与 ERB 输出页面。
bashruby --version
node --version
gem install hanami
hanami new bookshelf
cd bookshelf
bin/setup
bin/hanami dev
# 在浏览器打开 http://localhost:2300ruby# config/routes.rb
module Bookshelf
class Routes < Hanami::Routes
root to: "home.index"
resources :books, only: [:index, :show, :new, :create]
end
endruby# app/actions/books/create.rb
module Bookshelf
module Actions
module Books
class Create < Bookshelf::Action
include Deps["repos.book_repo"]
params do
required(:book).hash do
required(:title).filled(:string)
required(:author).filled(:string)
end
end
def handle(request, response)
return unless request.params.valid?
book = book_repo.create(request.params[:book])
response.redirect_to routes.path(:book, id: book.id)
end
end
end
end
endbashbin/hanami generate migration create_books
bin/hanami db migrate
bin/hanami generate relation books
bin/hanami generate repo bookruby# app/repos/book_repo.rb
module Bookshelf
module Repos
class BookRepo < Bookshelf::DB::Repo
def all_by_title
books.order(books[:title].asc).to_a
end
def get!(id)
books.by_pk(id).one!
end
def create(attributes)
books.changeset(:create, attributes).commit
end
end
end
endruby# app/views/books/index.rb
module Bookshelf
module Views
module Books
class Index < Bookshelf::View
include Deps["repos.book_repo"]
expose :books do
book_repo.all_by_title
end
end
end
end
endhtml<!-- app/templates/books/index.html.erb -->
<header>
<p>BOOKSHELF</p>
<h1>所有图书</h1>
</header>
<ul class="book-list">
<% books.each do |book| %>
<li>
<a href="<%= routes.path(:book, id: book.id) %>">
<%= book.title %>
</a>
<span><%= book.author %></span>
</li>
<% end %>
</ul>bash# 执行项目测试
bundle exec rake
# 检查可用命令与路由
bin/hanami routes
# 生产环境通常由 Rack 服务器启动
HANAMI_ENV=production bundle exec puma -C config/puma.rb下一步:新项目应使用 Ruby 3.3 或更高版本,并优先通过 bin/hanami 执行命令;先在单一 app 目录中保持简单,只有出现清晰领域边界后再拆分 Slice。
类似项目
这些 Ruby 工具覆盖从静态生成、轻量 Rack 路由到约定优先全栈开发的不同复杂度。
Hanami vs Ruby on Rails
Hanami 与 Rails 都能构建完整 Ruby Web 应用,但采用不同取向:Rails 通过强约定、集成式工具和庞大生态提升交付速度;Hanami 则通过独立组件、显式依赖和 Slice 强调长期边界与可替换性。
| 比较维度 | Hanami | Ruby on Rails |
|---|---|---|
| 设计理念 | 显式依赖、单一职责与可组合组件 | 约定优于配置与集成式全栈体验 |
| 请求处理 | 每个端点一个独立 Action 类 | Controller 聚合同一资源的多个 Action |
| 模块边界 | App 与 Slice 各自拥有容器和导入导出 | 以 Engine、命名空间和应用目录组织模块 |
| 依赖管理 | 容器自动注册并通过 Deps 显式注入 | 常依赖常量、框架生命周期与约定查找 |
| 数据层 | ROM Relation、Repo、Struct 与 Sequel | Active Record Model 同时承载查询和持久化 |
| 表现层 | View 对象、Exposure、Part、Context 与模板 | Controller 实例变量、Helper、Partial 与模板 |
| 生态与生产经验 | 社区精炼,第三方集成和案例相对较少 | Gem、教程、人才和大型生产案例非常丰富 |
| 更适合 | 强调领域边界、测试隔离和模块化单体的团队 | 重视快速交付、成熟生态和统一约定的团队 |
如果团队需要最快获得认证、管理后台、实时功能等成熟方案,依赖大量社区 Gem,或更容易招聘有经验的开发者,Rails 通常风险更低;如果团队愿意投入架构学习,并明确看重依赖注入、领域 Slice、独立 Action 与 ROM 的职责分离,Hanami 更能把这些约束变成框架默认。选择前应分别实现一个包含数据库、后台任务、邮件与测试的业务切片,而不只比较首页示例。
资料核验
版本、维护信息与本页采用的官方资料来源。
本次核验覆盖 Hanami 的核心定位、主要能力、官方入口与开源许可。项目版本持续更新,具体补丁版本、兼容性和迁移要求请在采用前继续核对官方发布记录。
官方仓库未归档,核验时最近可见的代码活动日期为 2026 年 7 月 23 日。该状态表示项目近期仍有公开维护活动,不代表固定发布频率或长期支持承诺。