So sánh không khách quan giữa Hanami và Rails
RubyOnRails
40
lotusrb
11
hanamirb
1
White

Lơi Rệ viết ngày 31/05/2016

Rails vs Hanami

Sau hơn 8 năm sử dụng Rails (và vẫn cho đến những ngày hôm nay), Rails làm một cuộc cách mạng lớn trong xây dựng phần mềm nền tảng Web với ngôn ngữ Ruby, hay có thế nói là Rails đưa vị trí Ruby lên hàng ghế anh chị trong các ngôn ngữ trên thị trường.

Nhưng nếu ai hỏi tôi họ có nên học Rails hay không thì lời khuyên của tôi đều là không nên học Rails. Nếu người hỏi là các lập trình viên mới thì lời giải thích là Rails quá phức tạp tuy dễ dùng, và người học Rails thường thiếu những kiến thức căn bản mà Rails đã xử lý và che đi. Còn nếu người hỏi là những lập trình viên có kinh nghiệm đến từ các ngôn ngữ khác thì tôi chỉ thằng vào những anti-pattern và chủ nghĩa cực đoan của DHH và cộng đồng Rails.

Trong bài viết này, tôi xin được mạn phép đưa ra những so sánh hoàn toàn không khách quan và mang tính cá nhân, tôi sẽ ráng cho người đọc một bài so sánh quả cam và quả táo hay nhất về Hanami vs Rails.

Hanami là gì?

Hanami là web framework mới dựa trên nền Rack với cấu trúc modular, cấu trúc đơn giản và được thiết kế giúp người dùng dễ dàng phân cách concern. Framework này được thiết kế bởi anh Luca Guidi trong suốt 10 năm, anh quyết định mã nguồn mở dự án vào năm 2014. Dự án hiện đang được ra tích cực phát triển, với phiên bản 0.8.0 sẽ được xuất bản trong 1 tháng nữa.

Rails là gì?

Rails là web framework 10 năm tuổi, với chú trọng vào Convention Over Configuration, dễ dàng prototype, và có một ecosystem các gem hỗ trợ khổng lồ. Dự án Rails được tạo ra bởi anh David H. Hasson cho dự án Basecamp, sau đó anh mã nguồn mở Rails và tạo ra một trào lưu sử dụng Ruby để phát triển ứng dụng Web. Hiện bản 5.0 đang được phát triển với nhiều chức năng mới hướng vào các ứng dụng nhúng sử dụng Backend API.

Tại sao nên dùng Hanami thay vì Rails?

Đây là câu hỏi mà tôi thường được hỏi nhất khi giới thiệu về Hanami. Vâng, tôi luôn trả lời lại là quá táo không là quả cam nhưng phản hồi của người nghe dường như cứ nghĩ tôi đùa cợt với họ... Thế tôi xin đưa ra so sánh sau đây, hoàn toàn mang tính cá nhân và khá là thiên vị Hanami.

Cấu trúc Monolithic không phù hợp cho cty lớn

Rails nổi tiếng với cấu trúc monolithic mà vẫn được việc, điều đó chứng minh rõ nhất thông qua kinh nghiệm đi làm của tôi, từ dự án enterprise nhỏ đến dự án khổng lồ như hệ thống Envato Marketplace tôi đang đảm nhiệm thì Rails đạt các yêu cầu đề ra của doanh nghiệp. Vớl trên 90 triệu request mỗi tuần thì Rails xử lý êm ru với sự hỗ trợ cả một binh đoàn server hùng hậu, được việc nhưng không hiệu quả về kinh tế, các bạn đọc có thể biết được bao nhiêu tiền cty tôi đang bỏ ra. Nhưng tiền thuê server thì vẫn rẻ hơn tiền thuê các kỹ sư, vấn đề của Rails tôi nhận thấy là không phù hợp chính sách scale up của các sản phẩm lớn, tuy tôi biết có nhiều cty có các giải pháp workaround như một bài của kỹ sư bên cty bên Cookpad. Nhưng dù gì thì nó cũng là workaround, vấn đề vẫn tồn tại, là rất khó để xé Rails app ra từng mảng nhỏ để dễ dự trù devops. Mặc dù thuê thêm nhiều lập trình viên nhưng hiệu suất công việc vẫn kém vì nhiều logic bị dính chùm và rất khó không 'dẫm vào chân' người khác khi phát triển, và trong 1 năm đổ lại thì cty tôi đang nỗ lực để xé nhỏ app ra thành nhiều app nhỏ để các team có thể độc lập phát triển mà không sợ ảnh hưởng đến team khác. Và vâng...không dễ như nói...

Nhưng điều đó không có nghĩa là các framework hướng microservices sẽ tốt hơn, vì sẽ có những vấn đề khác phải xử lý . Thế Hanami thì sao? Cấu trúc modular của Hanami là kiểu rời, không phải microservice, đúng hơn là ở giữa monolithic và microservice. Bời vì Hanami bắt buộc người viết suy nghĩ về cách cấu trúc phần mềm từ lúc mới viết để sao cho các concern được cách biệt rõ ràng, điều này giúp cho việc xé các component ra thành 1 app riêng khi yêu cầu cần scale trở nên rất đơn giản, và cũng nhờ không phải là microservices nên người dùng không mấy phải quan tâm đên các vấn đề của microservices như queuing, contract, vv.. Nhưng cũng có một tác hại phụ là người viết sẽ mất nhiều thời gian khi phát triển ý tưởng, không phù hợp với mục đính prototype nhanh.

Business Logic ở đâu?

Lại một câu hỏi mà nhiều bạn của tôi đến từ thế giới Java hay hỏi...Thực sự sau một hồi chỉ họ vào model rồi lộn ngược lên controller rồi lại lộn ngược model thì có lẽ họ đang nhìn tôi với một con mắt ngờ vực tôi đang troll chăng. Vâng, Rails nổi tiếng là về các mặc định nhưng lại không có những mặc định hay good practice về chỗ nào nên bỏ business logic. Bời vì thế trong những năm đầu của Rails, người dùng bỏ hết vào controller dẫn đến mực độ báo động bị nhồi máu cơ tim cho người đọc, rồi sau đó cộng đồng khuyên nhau bỏ vào các ActiveRecord model và cũng một thời gian ngắn sau thì cũng lặp lại tình trạng béo phì, và những năm gần đây là sử dụng Service Object. Để làm cho framework dễ dùng cho những lập trình viên thiếu kinh nghiệm, DHH đã phải hy sinh những luật cơ bản để viết phần mềm tốt, ví dụ luật Single Responsibility hay nên làm một việc cho tốt thay vì ôm đồm quá nhiều việc, tiếc thay là khi nhìn vào ActiveRecord với vô số các nhiệm vụ, từ validation đến persistence và nhiều thứ mà tô không dám nói ra. Thêm vào nữa Rails gắn liền model với phần form template ở View, khiến cho việc viếc các form mà cần đảm nhiệm với nhiều model trở nên ngượng ngạo, còn nếu ai nói phương pháp nested_attributes là giải pháp thì có lẽ họ chưa nếm mật nằm gai... Có thể nói là liệu sự trả giá để phần mềm dễ dùng vs đơn giản là quá đắt...

Lại nói về Hanami, Hanami có component hanami-model, tương đương với ActiveRecord. Component này không gộp mọi thứ vào model object mà phân nhiệm vụ ra làm 2 mảng lớn thông qua Repository pattern. Trong đó Entity object sẽ đảm nhiệm việc khởi tạo object và các logic liên quan đến model, và Repository object sẽ đảm nhiệm việc lưu trữ vào lớp lưu trư như Database. Kết hợp với các service object (được gọi là Interactor) và Form object (có thể nhúng và tự tạo) giúp đơn giản hoá trách nhiệm của từng lớp, giúp cho việc đọc và test rất đơn giản và dễ hiểu. Còn một điểm nữa của Hanami mà tôi rất thích là các logic lớp model được tách biệt ra và được đặt vào thư mục /lib và được chia sẻ với các app, điều này giúp người viết dễ dàng tìm thấy các logic ở cùng một nơi. Nhược điểm lớn nhất của Hanami ở mảng này là hanami-model vẫn còn thiếu nhiều chức năng của ActiveRecord, và nó gây nhiều trở ngại cho việc phát triển.

Tôi chỉ mong DHH không bao giờ phát triển Web Frontend vì ông ta sẽ là người tệ nhất tôi từng thấy..

Với một tư tưởng cố hữu, DHH vẽ ra một bức tranh frontend nhuốm màu đỏ của Ruby. Nếu ai theo dõi Rails từ xưa hẳn đã biết các bản đầu của Rails có sử dụng RJS, công nghệ này cho phép người dùng viết frontend form bằng Ruby và ít lâu sau ý tưởng đó đã được chứng mình là rất tệ hại, với các bản sau đó thì DHH xoá hẳn RJS và thay vào thuần jQuery. Cứ tưởng các sai lầm dừng lại ở đó, anh lại cho ra một cú sốc thứ hai cho cộng đồng web frontend qua việc giới thiệu Asset Pipeline. Chức năng này được đưa ra với hi vọng toàn bộ các package của JS/CSS frontend sẽ được quản lý qua các gói rubygems và sprocket sẽ quản lý toàn bộ phần quản lý các asset đó. Thứ nhất là frontend dev không sử dụng rubygems, thay vào đó họ sử dụng npm, bower và các công cụ trên nền JS khác của họ, điều đó dẫn đến không thể kiếm được các gói frontend package cho Ruby. Thứ hai là tốc độ compile asset thì vâng, chứng tỏ được là single-thread Ruby có thể chậm hơn được nữa, cũng may là những bản gần đây cũng cải thiện nhưng không thể nào so sánh với các giải pháp bên JS (con số giây vs con số phút). Và với công bố về ActionCable, tôi hi vọng địa ngục sẽ gần hơn 1 bước nữa cho tất cả Rails developer.

Chưa hết, nếu bàn về cách Rails cấu trúc phần View của model MVC, thì Rails chỉ phù hợp cho các app đơn giản, không phù hợp các app phức tạp nhiều yêu cầu về frontend hiện tại. Thứ nhất là Rails không có định nghĩa lớp presenter riêng ra, thay vào đó controller đảm nhiệm nhiệm vụ sẽ render gì, nhúng helper gì, và hiển thị những data gì trên template. Nếu xét vào cách viết Rails hồi hồng hoang thì có lẽ cả cái app chỉ cần có controller là đủ. Với Rails cái gọi là View thực ra là template, và Rails có một view context singleton object với các thông tin truyền từ controller vào thông qua các biến instance variables, điều này rất tai hại là vì người viết nếu không nghiêm với cách truyền biến thì biến này sẽ bị rò rỉ qua nhiều template. Không dừng ở đấy Rails khuyến khích người dùng sử dụng helper và các hàm hook như content_for để nhúng vào những logic frontend phức tạp. Nhân tiện chúng ta đang nói về helper, thì tôi xin giới thiệu với bạn helper, về mặt bản chất chỉ là module, module này được dùng như mixin các widget người dùng tự tạo vào View, nhưng khổ nỗi viết helper để tạo ra các HTML thì ôi thôi quá khó, nếu bạn đã từng đã viết qua thì mới thấy cách gọi hàm concat để nói các tag ôi thôi quá là khó. Và bạn muốn test các helper hay view? Chúc bạn may mắn, bời vì không có cách nào để test mà không bị hiệu ứng phụ của controller, và sẽ rất mất nhiều thời gian để setup test. Vì những thiếu sót trong cấu trúc Rails mà các cty hiện tự giới thiệu lớp presenter (tuỳ là không hoàn hảo), các giải pháp cấu trúc presenter như Aldous hay Trailblazer hiện cung cấp một cách tiếp cận khác, thực sự tiếc là DHH khá là cứng đầu và bảo thủ.

Thế lại bàn về Hanami, Hanami có phân rõ ràng lớp View, hay View class, lớp này sẽ xử lý tất cả những logic liên quan template, thêm vào đó người dùng có thể nhúng vào hanami-helper để tạo ra những HTML form phức tạp (và rất dễ viết helper). Ngoài ra controller cung cấp hàm expose cho phép người dùng truyền vào data nào mà người dùng muốn sử dụng cho View và template. Còn về mảng cấu trúc template, hiện Hanami chưa quyết định một giải pháp nào, tôi và anh Luca hiện đang xem xét các giải pháp thay thế, vd: sử dụng JS stack của cộng đồng frontend, hoặc kết hợp cùng phương pháp của Trailblazer? Tôi hi vọng sẽ đưa ra một giải pháp dễ dùng và gần gũi với thế giới frontend hơn.

Tôi cần hiệu chỉnh Rails để làm những thứ không được cung cấp bới Rails

Rails là một framework rất lợi hại, hầu hết các vấn đề thường gặp đều được giải quyết hoặc giải quyết vòng, nhưng một khi giải pháp yêu cầu cấu hình framework thì phải nói là không dễ, vì với lượng code dầy đặc và khá là phức tạp thì cấu hình lại yêu cầu kiến thức chuyên sau với một thời gian dài làm Rails.

Với Hanami thì codebase rất rõ và đơn giản, điều này tôi thấy rõ, với trường hợp các bạn sinh viên tham gia dự án RailsGirls Summer of Code có khả năng đọc và làm các PR dù cho chưa đụng vào Hanami bao giờ. Thêm vào nữa, Hanami trung thành với việc không bao giờ monkey-patch các core class như Rails, điều này đảm bảo rằng app của bạn sẽ không bị những hiệu ứng phụ. Hanami cam kết sẽ bám vào những pattern tốt và hạn chế tối đa giới thiệu những anti-pattern của Rails.

Rails chậm quá...

Vâng, với số lượng codebase khá là phức tạp thì việc Rails có chậm hơn Hanami là điều đương nhiên, nhưng tôi không giám chắc Hanami sẽ nhanh hơn nhiều một khi số lượng chức năng được đầy đủ như Rails.

Nhưng hiện tại thì chỉ có Rails mới cần gem spring để giúp tăng tốc phần loading, điều đó có thể thấy là số depedency của Rails sẽ chỉ tăng lên theo thời gian giết đi sự hiệu quả trong việc phát triển vì ...đợi.

Những con chiên ngoan đạo của Rails...

Sự sống của một framework chính là cộng đồng đứng sau đấy, tôi thực sự khá là thất vọng với cộng đồng Rails bây giờ, vì họ không bao giờ giám thách thức những quyết định của giáo chủ DHH. Và ai mà giám đứng lên thách thức hay chê bai thì đều bị các con chiên trù dập và lơ đi, điều này thực sự là tai hại vô cùng.

Dĩ nhiên bất kì ở đâu cũng cần một người lãnh đạo, nhưng tôi không đồng lòng với cách cộng đồng Rails đang hướng đến. Và cũng chính vì thế tôi và anh Luca luôn hướng đến một cộng đồng cở mở hơn, chúng tôi sẽ luôn rộng mở tiếp nhận ý kiến và không ngần ngại xin lỗi và sửa sai. Chúng tôi tin vào sức mạnh của cộng đồng chứ không phải vào một sức mạnh siêu nhiên của một DHH.

Kết luận

Tôi muốn nhấn mạnh lại rằng, không thể nào so sánh được Hanami và Rails.

Các bạn và tôi đều là kỹ sư phần mềm, tôi mong các bạn luôn luôn cởi mở để tiếp nhận những giải pháp và góc nhìn khác về cùng một vấn đề để có thể lựa chọn được một giải pháp tốt nhất có thể. Xin các bạn đừng trở thành những tín đồ mù quáng, điều đó là điều tai hại nhất, cản trở sự phát triển của kỹ sư phần mềm.

Dù nói xấu Rails nhiều thế kia, tôi vẫn phải ca ngợi là Rails rất trung thành với lý tưởng làm cho việc phát triển app từ A đến Z trở nên đơn giản cho tất cả mọi người, và tôi vẫn sẽ sử dụng Rails nếu phù hợp với yêu cầu công việc.

Hi vọng các bạn độc giả không phản hồi ném đá. Và tất cả ý kiến trên đều là ý kiến riêng của tôi, không đại diện cho dự án Hanami mà tôi tham gia phát triển.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Lơi Rệ

43 bài viết.
222 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
70 12
Sự sống còn của các công ty kỹ thuật phụ thuộc vào nguồn nhân lực chất xám của họ. Thế nên rất thiết yếu cho việc đầu tư xây dựng team có khả năng ...
Lơi Rệ viết hơn 2 năm trước
70 12
White
40 7
Trời se se lạnh, Melbourne chuyển mùa, ngồi trong quán cafe bắt đầu một ngày làm việc mới với suy nghĩ tại sao các bạn Việt Nam không muốn tham gia...
Lơi Rệ viết 3 năm trước
40 7
White
36 15
Thế nào là làm việc từ xa? Internet, một trong những phát minh vĩ đại nhất của con người thế kỷ 20. Công nghệ này xoả bỏ rào cản vật lý giữa các n...
Lơi Rệ viết hơn 2 năm trước
36 15
Bài viết liên quan
White
8 1
Tiếp theo (Link) Mình sẽ hướng dẫn cách test căn bản cho API mình tạo. Thật ra mà nói thì mình phải viết test trước khi làm nhưng mà để tránh việc...
My Mai viết 3 năm trước
8 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
43 bài viết.
222 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!