Bài viết này được cập nhật ngày 23 tháng 5 năm 2024 để làm rõ sự khác biệt về models và data persistence giữa Rails và Hanami.
Ruby on Rails là web framework phổ biến nhất trong hệ sinh thái Ruby và có lượng người dùng lớn, từ freelancer đến các công ty lớn thành lập. Với cộng đồng người dùng tích cực và tài liệu phong phú, nó có thể dùng để xây dựng mọi thứ từ ứng dụng đơn giản đến nền tảng web phức tạp.
Tuy nhiên, một đối thủ mới đang thách thức vị thế thống trị của Rails cho danh hiệu full-stack Ruby framework: Hanami. Đây là một Ruby framework nhanh, modular với hiệu suất và khả năng bảo trì cải thiện so với Rails.
Trong bài viết này, chúng ta sẽ khám phá điểm mạnh và điểm yếu của từng framework về hiệu suất, tính năng, testing, và hơn thế nữa. Vì vậy, dù bạn muốn xây dựng web app hướng khách hàng, công cụ nội bộ, hoặc API scalable lớn, bạn sẽ rời đi với sự hiểu biết tốt hơn về cái nên dùng cho dự án tiếp theo.
Hãy bắt đầu với giới thiệu ngắn gọn về từng framework.
Giới thiệu Ruby on Rails
Ruby on Rails là framework phát triển ứng dụng web Ruby nổi tiếng nhất với sứ mệnh nâng cao năng suất nhà phát triển (bằng cách đưa ra một loạt giả định về cách app nên được xây dựng, thường được gọi là "Rails way").
Một số giả định này bao gồm đảm bảo nhà phát triển không mất thời gian cấu hình mọi thứ, hay còn gọi là "convention over configuration", và nhấn mạnh vào việc sử dụng nguyên tắc DRY ("don't repeat yourself"). Nguyên tắc DRY khuyến khích nhà phát triển tránh lặp lại code liên tục, mà thay vào đó dùng các biểu diễn đơn lẻ, tập trung của chức năng app để đảm bảo khả năng bảo trì và tổ chức.
Giới thiệu Hanami
Trong khi Rails rất nổi tiếng trong cộng đồng Ruby, Hanami thì ít được biết hơn. Đây là một Ruby framework hiện đại khá mới, cố gắng thách thức sự thống trị của Rails trong không gian full-stack web framework.
Hanami được xây dựng từ nền tảng để có memory footprint nhỏ và tập trung vào modularity, thứ mà, lần lượt, tạo ra một framework rất nhanh và linh hoạt.
Rõ ràng, những giới thiệu ngắn gọn này sẽ không cung cấp đủ thông tin để bạn quyết định framework phù hợp nhất. Để làm vậy, chúng ta cần đi sâu hơn vào từng cái, bắt đầu với cách chúng được cấu trúc.
Cấu trúc và Kiến trúc của Rails và Hanami
Rails và Hanami có chút tương đồng ở chỗ cả hai đều là Ruby framework. Tuy nhiên, cách mỗi cái được xây dựng và kiến trúc ứng dụng của chúng là nơi bạn sẽ tìm thấy hầu hết sự khác biệt.
Thứ nhất, với Rails, bạn có ít file hoặc abstraction (khối xây dựng bạn dùng để build app) hơn, những cái này có xu hướng lớn dần về kích thước khi bạn phát triển app. Mặt khác, Hanami đưa abstraction lên một tầm mới, với nhiều file mà kích thước thường nhỏ hơn.
Các sơ đồ dưới đây minh họa điểm đó rõ ràng hơn. Hãy bắt đầu với Rails.

Bây giờ so sánh sơ đồ abstraction của Rails với sơ đồ Hanami dưới đây.

Như bạn thấy, mỗi framework nói chung tuân theo cấu trúc model-view-controller (MVC). Tuy nhiên, Hanami đưa abstraction lên cấp độ tiếp theo.
Dưới đây là outline đơn giản về cách tổ chức của từng framework:
- Routes - Mỗi framework có định nghĩa routes với các endpoint của app.
- Controllers vs. actions - Trong Rails, bạn có controllers với một hoặc vài action trong đó. Controllers nhận và phản hồi route requests bằng cách điều hướng chúng đến action liên quan. Trong Hanami, không có controllers. Thay vào đó, bạn đi thẳng đến self-contained actions (mỗi action có class tự chứa của riêng nó).
- Models và persistence - Layer model của Rails lo data validation và database communication, bao gồm mọi query app có thể có. Persistence được xử lý bởi Ruby Object Mapper (ROM). Trong Hanami, layer model trừu tượng hơn, tách thành entities và repositories. Entities xử lý domain logic và database-agnostic, trong khi repositories (repos) dùng để giao tiếp với database. Hanami 2.0 trở đi ship không có persistence layer pre-configured, cho phép bạn chọn ORM phù hợp hoặc lập trình không ORM.
- View rendering - Giống như persistence layer, view của Ruby on Rails thường chứa mọi thứ cần thiết để render data ra bên ngoài ở một nơi. Đó bao gồm toàn bộ cấu trúc HTML, view helpers, và view logic. Khi nói đến view rendering trong Hanami, mọi thứ trừu tượng hơn. Để bắt đầu, bạn có views sử dụng bất kỳ view helpers nào app có và cũng render template. Template xử lý cấu trúc HTML thực tế, trong khi parts lo presentation logic.
Vậy tất cả điều đó có nghĩa là gì khi xây dựng app? Với ít abstraction hơn, Rails là lựa chọn tốt để khởi động app và thân thiện với người mới (như chúng ta sẽ thấy sau). Với Rails, bạn có thể xây dựng monolith app rất robust, nhưng code sẽ càng phức tạp khi scale. Mặt khác, cấu trúc phức tạp hơn của Hanami có thể khiến người mới nản lòng, nhưng nó cho phép bạn xây dựng ứng dụng scalable lớn và có thể tổ chức code tốt hơn nhiều.
Tiếp theo, hãy xem ecosystem của từng framework.
Ecosystem và Community
Như đã đề cập trước đó, Rails có framework thành lập hơn Hanami. Rails tồn tại lâu hơn và, do đó, có cộng đồng lớn và trưởng thành hơn.
Sự khác biệt về ecosystem và community được tóm tắt dưới đây:
- Documentation - Không quan trọng bạn đang cố xây dựng gì, nếu bạn dùng Rails, bạn có quyền truy cập tài liệu rất 잘 done. Bạn được hướng dẫn qua tất cả các phần của việc build app, từ authentication, đến data persistence, view presentation, và mọi thứ ở giữa. Ngoài ra, một loạt third-party tutorial bao phủ hầu như mọi thứ có thể tưởng tượng về việc xây dựng ứng dụng.
Đó là nói về Rails. Còn về phía Hanami, mọi chuyện chưa được thiết lập như vậy. Với tư cách là framework tương đối mới, Hanami có cơ sở tài liệu hạn chế hơn. Đội ngũ Hanami đã làm việc ấn tượng với official guides, nhưng so với cơ sở tài liệu Rails, nó không thể so sánh được.
- Community - Ở đây, cũng như documentation, Rails là người thắng rõ rệt. Rails tồn tại lâu hơn Hanami nhiều, nên nó được adopt nhiều nhất. Không quan trọng bạn là beginner hay advanced developer, bạn sẽ tìm thấy cộng đồng Rails trên subreddit, Slack groups, Discords, v.v. Mặt khác, Hanami vẫn đang lớn, nghĩa là có community nhỏ hơn nhiều.
- Gems và libraries - Vì cả Hanami và Rails đều là Ruby framework, có thể lập luận rằng gems hoạt động trong Rails sẽ hoạt động trong Hanami. Mặc dù điều này đúng về mặt kỹ thuật, bạn thường sẽ thấy Rails có cơ sở gems và libraries thành lập hơn cho mọi loại chức năng chuyên biệt.
Đó là nói về/gems. Tuy nhiên, nhờ focus vào abstractions và specialization, Hanami có một số gems rất advanced có thể đưa Rails app của bạn lên tầm cao mới. Ví dụ, default dry-rb gems trong Hanami có thể mang lại tổ chức code và abstraction tốt hơn khi dùng trong Rails apps.
Tiếp theo, hãy so sánh learning curve và adoption của từng framework.
Độ dễ sử dụng, Adoption, Governance, và Learning Curve
Với những lý do nêu ở phần trước, Ruby on Rails dễ dàng đánh bại Hanami về độ dễ dùng, adoption trong ngành, và learning curve, cụ thể:
- Learning - Hãy tưởng tượng bạn là beginner hoàn toàn muốn học ngôn ngữ lập trình mới. Suy nghĩ đầu tiên sẽ là check online learning resources. Nếu một framework có tài liệu học tập rộng rãi bao phủ quá trình build app từ đầu đến cuối, bạn có khả năng chọn framework đó hơn những cái khác. Vì Rails có cơ sở tài liệu thành lập hơn, nó thắng Hanami như lựa chọn của beginner. Ngoài ra, Rails thân thiện hơn với beginner vì nó đưa ra nhiều giả định under the hood (so với Hanami, cung cấp cách build app trừu tượng hơn). Abstraction của Hanami có thể gây nản chí ngay cả cho Rails developer đã có kinh nghiệm.
- Industry adoption - Không kể adoption của các framework phổ biến và thành lập khác như Python, React, C#, và những cái khác, nếu xét adoption của Ruby frameworks, Rails dễ dàng lấn át Hanami. Trang chủ Rails liệt kê một số tổ chức lớn dùng framework. Mặt khác, với tư cách là "new kid on the block", Hanami chưa được adopt rộng rãi. Chúng ta phải chờ xem liệu có thay đổi trong tương lai.
- Job market prospects - Về cơ hội việc làm, bạn sẽ tìm thấy nhiều job opening cho Rails developer hơn Hanami developer.
- Governance - Một khía cạnh quan trọng khác không thể bỏ qua là governance. Một landscape thay đổi hướng dẫn cách các open-source framework tiến hóa và phát triển. Tuy nhiên, hơn thế nữa, core team members của các framework này thường nắm quyền lực lớn và có thể quy định cái gì vào framework, nó phát triển như thế nào, v.v.
Một ví dụ tốt là thông báo tháng 1 của David Heinemeier Hansson (DHH), người tạo ra Rails. Anh ấy nói rằng, trong tương lai, anh sẽ đẩy Rails cung cấp first-class support cho việc xây dựng full-stack progressive web applications và native notifications. Những tính năng này sẽ làm Rails rất hấp dẫn cho mobile developers.
Phản ứng lại, nhiều developer, một số bên ngoài hệ sinh thái Ruby và thậm chí những người đã bỏ Rails nhiều năm, phản ứng cực kỳ tích cực, nói rằng họ sẽ vui vẻ pick up framework hoặc học nó nếu DHH giữ lời. Ví dụ này chỉ ra rằng governance là một cân nhắc rất quan trọng khi quyết định chọn framework nào.
Hãy chuyển sang điều kỹ thuật hơn: application performance.
Performance: Ruby on Rails vs. Hanami
Là một developer, bạn sẽ quan tâm đến reliability, responsiveness của app, và cách nó sử dụng server resources khi deploy lên production. Những lo ngại cơ bản này có thể ảnh hưởng lớn đến lựa chọn framework của bạn.
Bạn có thể dùng nhiều phương pháp để chạy performance tests trên app, một trong những phổ biến nhất là Apache JMeter. Hãy dùng benchmark numbers để so sánh Hanami và Rails.
Đây là một quick benchmark test cho thấy số requests mỗi framework có thể handle per second:

Hanami thắng Rails hoàn toàn, với khả năng handle 3 lần nhiều requests hơn Rails.
Screenshot tiếp theo cho thấy giá trị latency trung bình cho mỗi framework:

Lại một lần nữa, Hanami thắng Rails với average latency time ngắn hơn khoảng 3 lần.
Nếu bạn tìm một Ruby framework blazingly fast (giả sử bạn cần làm việc trên API nhanh và scalable lớn), bạn sẽ khó tìm thấy cái gì tốt hơn Hanami trong bối cảnh Ruby.
Testing
Khi nói đến testing code, cả hai framework rất comparable vì bạn có thể test cả hai bằng thư viện RSpec linh hoạt.
RSpec được include qua gem hanami-rspec cho Hanami apps, trong khi bạn cần cài gem rspec-rails để dùng trong Rails app. Ví dụ dưới đây cho thấy một test spec cơ bản đi kèm với Hanami app mới:
Chạy nó với $ bundle exec rspec spec/requests/root_spec.rb nên cho kết quả passing test (giả sử bạn chưa edit default view template):
Ở phía Rails, bạn cần tự xử lý một số việc. Trước tiên, bạn cần thêm RSpec gem vào development/test block trong Gemfile như dưới đây, rồi chạy bundle:
Bước tiếp theo là chạy RSpec install với command bundle exec rails generate rspec:install để chuẩn bị cho Rails project.
Cuối cùng, trước khi viết và chạy bất kỳ test nào, bạn có thể cần cài thêm gem để định nghĩa test data cho Rails app: FactoryBot.
Và giả sử bạn đã setup test suite đúng và định nghĩa vài test, bạn có thể chạy test giống như Hanami, với bundle exec rspec spec/models/user_spec.rb. Bạn có thể nhận kết quả test giống như Hanami app:
Cuối cùng, hãy xem frameworks so sánh như thế nào về deployment.
Deployment
Ngày nay, có nhiều options để deploy Ruby apps lên production.
Để bắt đầu, bạn có thể chọn Platform-as-a-Service (PaaS) provider như Heroku, hoặc Fly cho trải nghiệm seamless hơn. Bạn cũng có thể làm chút DevOps: setup Docker installation trên VPS và deploy app đó.
Dù chọn option nào, bạn có thể mong đợi deployment tương đối giống nhau trong cả hai trường hợp. Chỉ có caveat là thiếu tài liệu và tutorial mở rộng cho việc deploy Hanami apps.
Như đã chỉ ra trước đó, vì là framework mới hơn, Hanami vẫn chưa có tài liệu mở rộng bao phủ quá trình deployment và những challenge có thể nảy sinh. Nếu bạn không ngại hack around this, thì bạn nên ổn.
Kết thúc
Trong bài viết này, chúng ta đã xem hai Ruby framework — Ruby on Rails và Hanami — so sánh chúng về features, architecture, performance, và hơn thế nữa. Cuối cùng, chúng ta phải trả lời câu hỏi: "Tôi nên dùng framework nào, và tại sao?". Chúng ta có thể tóm tắt như sau:
- Nếu bạn là Ruby developer mới, hãy bắt đầu với Rails: nó dễ học hơn. Nếu bạn là Ruby developer nâng cao, hãy phát triển skillset Hanami, vì nó sẽ giúp bạn develop ứng dụng Ruby robust hơn nữa.
- Nếu bạn cần develop app cần nhanh, ví dụ API phục vụ nhiều client, memory footprint nhỏ, response nhanh như chớp, và low latency của Hanami sẽ phục vụ bạn tốt. Tuy nhiên, nếu bạn chỉ cần develop monolithic full-stack app để validate ý tưởng SaaS, Rails chắc chắn đưa bạn đến đó nhanh hơn.
Cuối cùng, cái bạn chọn thực sự tùy thuộc vào bạn. Không phải ý tưởng xấu để có skill cả hai framework. Cách đó, bạn có thể quyết định framework tốt nhất tùy thuộc vào nhu cầu dự án.
Happy coding!
P.S. Nếu bạn muốn đọc các bài Ruby Magic ngay khi chúng ra mắt, hãy subscribe newsletter Ruby Magic của chúng tôi và không bao giờ bỏ lỡ bất kỳ bài viết nào!
P.P.S. Bạn có biết AppSignal có integration cho Rails và Hanami?