3 điểm bởi GN⁺ 2024-11-04 | 2 bình luận | Chia sẻ qua WhatsApp
  • Sau khi cân nhắc nhiều stack khác nhau cho ứng dụng lập tờ khai hải quan, Ruby on Rails quen thuộc được dùng cho triển khai ban đầu vì cảm nhận là có thể tạo tính năng nhanh hơn rất nhiều so với các lựa chọn mới
  • “version 2” dùng backend Rust và frontend SvelteKit chạy nhanh và trông đẹp, nhưng chỉ đáp ứng khoảng 10% tính năng cần thiết, còn công việc đường ống hơn cả mã nghiệp vụ
  • Việc chuyển đổi dần dần đòi hỏi phải tự ghép nối routing, truy cập dữ liệu, phân quyền, theo dõi thay đổi, tìm kiếm, tác vụ nền, pub/sub, email, OAuth 2.0, SMTP/POP, object storage và tạo PDF, nên gần như không làm tăng giá trị cho người dùng
  • Cuối cùng quyết định đưa phần đã chuyển sang stack mới quay lại Rails, và quyết định này bị ảnh hưởng bởi việc một mình duy trì ứng dụng Rails, căng thẳng vì không đáp ứng được nhu cầu người dùng, cùng độ phức tạp khi phải sửa đồng thời ở nhiều nơi
  • Sau khi quay lại Rails, tốc độ phát triển tính năng, cải thiện tính năng cũ, cập nhật UI và sửa lỗi đã tăng trở lại; các nhược điểm của Ruby/Rails được xử lý bằng kiểm thử, refactor, Turbo và caching để tập trung vào phát triển sản phẩm

Điểm khởi đầu: chọn Rails như một phương án tạm thời

  • Năm 2022, khi bắt đầu xây dựng ứng dụng lập tờ khai hải quan, tác giả đã xem xét nhiều ngôn ngữ và framework như .NET/F#, Go, Rust, React và thực sự viết thử mã với chúng
  • Lựa chọn cuối cùng là Ruby on Rails
    • Đây là công cụ đã quen thuộc, và cảm nhận là có thể tiến nhanh hơn gấp 10 lần so với các lựa chọn phải học mới
  • Khi đó, bản triển khai bằng Rails gần giống một proof of concept tạm thời, và về sau có kế hoạch viết lại bằng một ngôn ngữ khác không “dễ mắc sai lầm” như Ruby
  • Ứng dụng Rails nhanh chóng bổ sung được nhiều tính năng, và đồng nghiệp cũng thích kết quả tạo ra
    • Có thể nhanh chóng xây dựng các tính năng giúp tăng năng suất
    • Ban đầu còn có thể dùng mã để chặn các tình huống lỗi xảy ra thường xuyên

Điểm nghẽn của “version 2” với Rust và SvelteKit

  • “version 2” chọn Rust cho backend và SvelteKit cho frontend
  • Bản đầu tiên trông đẹp và chạy nhanh, nhưng chỉ có khoảng 10% số tính năng cần thiết
  • Rust không có framework tích hợp tương đương với Rails, nên phải viết nhiều mã nền tảng và công việc kết nối hơn là logic nghiệp vụ
  • Dần trở nên rõ ràng rằng để hoàn thiện version 2 thì phải dừng hoàn toàn việc phát triển version 1, và cuối cùng version 2 bị loại bỏ
  • Việc viết lại được xác nhận là có thể mất thời gian gần tương đương với lúc xây dựng ứng dụng ban đầu

Độ phức tạp vận hành do chuyển đổi từng bước

  • Mong muốn đưa Rust vào ứng dụng vẫn còn đó vì kiểu tĩnh mạnh, hiệu năng nhanh và sự yên tâm khi biên dịch thành công
  • Dù đã dùng Ruby hơn 4 năm, các vấn đề runtime vẫn tiếp tục xảy ra
    • Chủ yếu là giá trị null và các ngoại lệ không được xử lý
    • Sau khi triển khai, tác giả theo dõi công cụ báo lỗi để nhanh chóng sửa sự cố production
  • Ở frontend Rails, điều gây khó chịu là logic và markup bị phân tán qua nhiều tệp, trong khi Svelte giúp gom logic liên quan vào một tệp dễ hơn
  • Kế hoạch là từ từ viết frontend mới bằng SvelteKit và backend mới bằng Rust, rồi dần thay thế cả phần Rails hiện có để cuối cùng loại bỏ Rails
  • Ban đầu, việc chuyển các trang “index” có danh sách bản ghi và bộ lọc sang stack mới diễn ra khá nhanh
    • Stack mới chạy nhanh và phần Rust hầu như không có vấn đề runtime
    • Các quy tắc triển khai để quyết định route nào đi tới Rails, Rust hay SvelteKit trở nên phức tạp
    • Độ phức tạp này được chấp nhận như trạng thái tạm thời cho tới khi chuyển đổi hoàn toàn

Công việc kỹ thuật lớn hơn giá trị người dùng

  • Theo thời gian, phía Rails tiếp tục được thêm các tính năng mới hữu ích, còn các tính năng hiện có cũng ngày càng sâu và tinh vi hơn
  • Đã có nhiều đợt refactor để sửa các giả định sai ban đầu, và tác giả kết luận rằng một schema cơ sở dữ liệu được thiết kế tốt sẽ có ích cho bất kỳ phiên bản nào
  • UI Rails được xem là sắp bị thay thế nên quyết định không đầu tư thêm nhiều thời gian vào đó
  • Vài tháng sau, việc kinh doanh thành công đủ để có thể tuyển lập trình viên toàn thời gian, và tác giả kỳ vọng quá trình chuyển sang Rust sẽ tăng tốc
  • Trên thực tế, rất nhiều thời gian trong stack mới bị dùng cho việc viết các tầng trừu tượng và cơ chế
    • truy cập cơ sở dữ liệu
    • xử lý phân quyền để người dùng chỉ nhìn thấy dữ liệu họ được phép xem
    • theo dõi mọi thay đổi
    • tìm kiếm và lọc
    • ép buộc ràng buộc thông qua hệ thống kiểu
  • Sau đó danh sách tính năng cần thiết còn tiếp tục dài ra
    • tác vụ nền
    • hệ thống pub/sub để cập nhật client
    • chức năng email
    • OAuth 2.0 để kết nối dịch vụ bên ngoài
    • SMTP và POP
    • object storage
    • tạo PDF
  • Thư viện Rust thì đủ dùng, nhưng công việc chọn thư viện phù hợp và kết nối tất cả lại với nhau là rất lớn
  • Các cuộc thảo luận về chi tiết triển khai kỹ thuật như chọn Rust ORM hay thời điểm phát hành và điểm cải tiến của Svelte 5 bắt đầu nhiều lên
  • Sau khoảng 1 năm viết Rust và Svelte, trở nên rõ ràng rằng người dùng hầu như không thu được lợi ích nào từ công việc này
    • Một số màn hình của stack mới mượt và nhanh, nhưng đó không phải những chỗ vốn là vấn đề
    • Những trang được dùng nhiều nhất vẫn chạy trên Rails, và có số tính năng nhiều hơn gấp 10 lần “bản beta” của stack mới
    • Có những khoảng thời gian vài ngày hoặc vài tuần trôi qua mà không thêm được giá trị trực tiếp nào

Quyết định quay lại Rails

  • Cuối cùng quyết định viết lại bằng Rails cho những phần đang chạy trên stack mới
  • Đây không phải là viết lại toàn bộ ứng dụng, mà là đưa những phần đã chuyển sang Rust/SvelteKit quay về Rails
  • Quyết định này khó khăn nhưng hợp lý
    • Đã đầu tư rất nhiều thời gian và mã nguồn
    • Có khả năng các thành viên trong nhóm không thích Ruby hay Rails
    • May mắn là cả nhóm hiểu quyết định này và sẵn sàng học cái mới
  • Điểm mạnh của Rails là nhiều tính năng có sẵn ngay từ đầu, hệ sinh thái thư viện trưởng thành và ổn định, cùng thiết kế giàu quy ước và quan điểm giúp mã ngắn gọn
  • Rails giúp tập trung vào việc làm sản phẩm và giảm gánh nặng phải tự viết mã hỗ trợ bên dưới

Những bài học còn lại sau khi trở về Rails

  • Nỗ lực với Rust và Svelte không hoàn toàn là lãng phí
    • Việc học ngôn ngữ và framework mới mang lại những góc nhìn và ý tưởng có ích cả ở các ngôn ngữ khác
    • Viết ứng dụng web là chuỗi liên tục của lựa chọn và đánh đổi
    • Hoặc chấp nhận khiếm khuyết của framework, hoặc tự đầu tư triển khai, và cần cân nhắc xem khoản đầu tư đó có tạo lợi thế cạnh tranh và phần thưởng dài hạn hay không
  • Việc đưa mọi thứ trở lại Rails phần lớn khá đơn giản và cũng làm giảm căng thẳng
  • Trong vài tuần gần đây, tác giả lại cảm nhận được năng suất trong phát triển tính năng mới, cải thiện tính năng cũ, cập nhật UI và sửa lỗi
  • Các nhược điểm của Ruby và Rails được chấp nhận như những điều kiện cần tính đến khi viết mã
    • Nếu có nhiều vấn đề runtime thì cần kiểm thử nhiều hơn
    • Mã spaghetti khó bảo trì thường dễ do lập trình viên tạo ra hơn là do ngôn ngữ hay framework
    • Cần dành nhiều thời gian hơn cho refactor và tổ chức mã
    • Nếu mở rộng Rails đã khó thì mở rộng thứ khác cũng khó
    • Rails đủ nhanh, và có thể lách qua bằng Turbo cùng caching
  • Từ góc nhìn người dùng, stack Rust không nhanh hơn rõ rệt
  • Trong Rails, P95 duration của trang nặng nhất là 338ms, vẫn còn chỗ để cải thiện nhưng đã đủ nhanh để tạo cảm giác ổn
  • Không có ngôn ngữ hay framework nào hoàn hảo; điều cần thiết là hiểu rõ điểm mạnh, điểm yếu và cách xử lý chúng
  • Rails là một trong những framework rất tốt cho người muốn tập trung làm ra sản phẩm, và những framework lâu đời khác với cộng đồng đóng góp năng động cũng có thể là lựa chọn tốt tương tự

2 bình luận

 
lemonmint 2024-11-04

Viết lại bằng Ruby
Viết lại bằng Rails

 
GN⁺ 2024-11-04
Ý kiến trên Hacker News
  • Tôi cho rằng Rails vượt xa các stack khác khi xây dựng ứng dụng web, kể cả Django hay Laravel
    Nó đã xử lý hết những phần nhàm chán, hiểu rõ các yêu cầu cần thiết và ít cản trở hơn khi làm ứng dụng thực tế. Sau 15 năm phát triển ứng dụng web, tôi đã dùng Meteor, Remix, Next.js, Node.js dựa trên Express và nhiều thứ khác, nhưng tôi thấy phát triển web về cơ bản đã là một bài toán được giải khá nhiều rồi. Phía JavaScript giống như các lập trình viên bị dòng tiền của các tập đoàn lớn đẩy sang việc nghịch đồ chơi mới, còn Rust hay Go thì tốt cho phát triển hệ thống và hạ tầng triển khai, nhưng nhét ép vào phát triển web thì không hợp lý

    • Dù không phải là stack đang thịnh hành, tôi cảm thấy Spring Framework/Spring Boot nhìn chung là stack ứng dụng web tốt nhất
      Nó tích hợp dễ dàng với vô số thư viện Java và là ngôn ngữ kiểu tĩnh nên hữu ích trong nhiều tình huống. Chỉ riêng việc binding dữ liệu theo quy ước thông qua Jackson cũng đã rất xuất sắc từ rất lâu rồi, trong khi ở các ngôn ngữ kiểu động, cảm giác những phần như vậy thường được vá thêm về sau
    • Các framework này giống như làn đường cao tốc để bắt đầu dự án vì không cần phải đưa ra nhiều quyết định lớn
      Nhưng sau khi đã đi sâu vào Rails, Django hay Laravel mà cần làm việc gì đó lệch khỏi quy ước thì có thể trở nên khó nhằn. Vì không tự tay viết glue code nên nhiều khi thứ xuất hiện là khoảng trống trong hiểu biết hơn là rào cản kỹ thuật. Dù vậy, nếu thật sự học kỹ bên trong thì chỉ riêng việc đọc code cũng có thể tiết kiệm rất nhiều thời gian lập trình. Tất nhiên trên thực tế người ta lại không làm vậy, vì viết lại từ đầu quá vui nên dù không hợp lý về mặt kinh doanh vẫn thích thử cái mới
    • Tôi không đồng ý. Rails rất tuyệt về mặt tính năng và năng suất, nhưng không phải là giải pháp vạn năng
      Đừng chỉ tin ý kiến của tôi, hãy xem dữ liệu: https://www.youtube.com/watch?v=Qp9SOOtgmS4
      Nếu dùng Rails cho một dịch vụ mà bạn không nắm chắc số người dùng hoặc số request mỗi giây, bạn có thể tiết kiệm chi phí ở thời điểm phát hành nhưng lại tốn thêm chi phí máy chủ
    • Với tư cách là người từng dùng AOLServer và từng làm ở một startup năm 1999 xây thứ giống Rails bằng Tcl, tôi không đồng tình lắm
      Bản demo của Rails không hấp dẫn đến vậy, ngoài việc cho thấy vận may quan trọng thế nào trong chuyện được chú ý và được chấp nhận. Đến giờ tôi vẫn không thấy rõ giá trị của nó và sẽ chọn Spring hoặc ASP.NET. Những nhà sáng lập của startup nền Tcl đó sau này đã tạo ra OutSystems, một trong số ít công cụ RAD thành công ở quy mô phát triển web doanh nghiệp và cũng là một câu chuyện thành công của ngành CNTT Bồ Đào Nha
    • Điều này phần lớn cũng áp dụng cho Django
      Trước đây tôi thích Rails hơn, nhưng trong hơn 10 năm qua Python đã phát triển mạnh nên Django trở thành lựa chọn thực tế hơn. Các lập trình viên machine learning và data science vốn đã quen với Python, còn tài liệu của Django thì quá tốt nên khi cần họ có thể đạt năng suất chỉ trong thời gian rất ngắn. Tôi đã tận mắt thấy điều đó ở nhiều dự án
      Django cũng giảm bớt các quyết định và tranh cãi về cấu trúc ứng dụng so với các thư viện kém áp đặt hơn hoặc các microframework. Cộng đồng Django/FLOSS cũng năng động hơn tôi tưởng rất nhiều, và việc tương tác với họ cũng rất dễ chịu. Chỉ là tôi ước nó có các generator kiểu Rails và tính năng seed dữ liệu tích hợp sẵn, ví dụ như rake db:seed
  • Tôi đã dùng Rails 17 năm rồi, vẫn rất thích và còn ưu tiên nó cho cả frontend
    Nó cho bạn mọi lựa chọn để tách code mà không biến phần đầu file thành một danh sách includes dài lê thê không cần thiết như trong các ứng dụng Angular. Tôi không thấy có nhược điểm nào trong việc tách logic và markup ở frontend. Có thể test logic một cách độc lập, và khi tìm bug thường biết được đó là vấn đề ở markup hay ở logic nên việc lần vết dễ hơn. Tôi cũng từng viết khá nhiều method Ruby dài hơn 200 dòng, nhưng đó hoàn toàn là lỗi của tôi, và nếu có hệ thống unit test chi tiết hơn thì đã ngăn được điều đó

    • Một cách khác để tránh danh sách includes dài là biến mọi thứ thành toàn cục
      Tôi không chắc đó có phải là ưu điểm hay không. Import có thể chiếm khá nhiều chỗ, nhưng nó cho thấy một cách tường minh mọi thứ được kết nối với nhau như thế nào. Nếu thấy vướng mắt thì cứ gấp chúng lại trong IDE
  • Tôi thích bài viết này vì nó thực tế. Câu cốt lõi này đáng để luôn ghi nhớ
    “Điều thú vị là những thứ từng làm tôi bực mình ở Ruby và Rails giờ đây đỡ khó chịu hơn nhiều. Tôi đã chấp nhận rằng không có ngôn ngữ hay framework nào là hoàn hảo. Chỉ cần biết điểm mạnh và điểm yếu của chúng rồi xử lý thôi”

    • Tôi thích sự thực dụng của bài viết. Nó giống như một bài nhập môn rất đáng đọc trước khi viết lại một thứ gì đó
    • Tôi thường cảm thấy những người phàn nàn về framework thường mang trong đầu một thế giới quan hoàn hảo mà họ không muốn thỏa hiệp
      Trong nhiều trường hợp họ chưa hiểu framework đủ sâu, và cũng không biết vì sao nó lại được thiết kế như vậy. Nhưng biết rõ giới hạn của nó và làm việc cùng framework hiệu quả hơn rất nhiều. Bạn nên dành thời gian để thực sự hiểu công cụ mình đang dùng
    • Câu đó xuất hiện sau bối cảnh của nỗ lực này
      “Trong thời gian qua, tôi đã bắt đầu xây dựng ‘phiên bản 2’ của ứng dụng. Tôi chọn Rust cho backend và SvelteKit cho frontend.”
      Vì v1 bắt đầu với Rails, tôi đọc nó như một lời nhắc hãy cẩn thận khi từ bỏ một framework vốn đã hoạt động tốt
    • Với tôi đây cũng là điều giác ngộ quan trọng nhất. Giờ tôi hạnh phúc hơn nhiều vì không còn mãi nghĩ kiểu “Giá như có enum của Rust!” nữa
  • Rust là một ngôn ngữ do những người rất thông minh tạo ra, nhưng có cảm giác trọng tâm của nó nghiêng nhiều hơn về lý thuyết kiểu và tiết kiệm thêm vài lần cấp phát, thay vì giúp một lập trình viên thực chiến như tôi tạo ra thứ gì đó hữu ích và nhất quán
    Dù đã dùng Rust từ năm 2020, mỗi khi đọc các bài viết blog về Rust tôi vẫn theo nghĩa đen là không hiểu được một nửa

    • Bạn có thể chia sẻ ví dụ nào khiến bạn cảm thấy Rust thiếu nhất quán không? Ngược lại, tôi thấy đây là một ngôn ngữ rất nhất quán, nhỏ gọn và được thiết kế tốt
      Đặc biệt là khi so với các ngôn ngữ chủ lưu khổng lồ. Ví dụ, trait bao trùm cả trường hợp sử dụng của abstract class và concept trong C++, cũng như abstract class và protocol trong Python. Cũng không có sự thiếu nhất quán kiểu nên dùng exception hay trả về giá trị để xử lý lỗi. Có panic, nhưng nó được dùng giống như assert. Khi if-else là một biểu thức thì cũng không cần toán tử ba ngôi riêng
    • Rust là một ngôn ngữ hệ thống, và trong lĩnh vực đó thì nó rất xuất sắc. Nếu so sánh với các ngôn ngữ cùng nhóm thì các bài blog về C++ cho cảm giác kém nhất quán hơn nhiều
      Gần đây có xu hướng muốn dùng Rust cho mọi thứ, nhưng đây không phải là ngôn ngữ được tạo ra để dùng cho ứng dụng CRUD. Suy cho cùng, bài viết này gần như là một nghiên cứu tình huống cho câu “hãy dùng công cụ phù hợp với công việc. Ngôn ngữ bạn thích trong thời gian rảnh hoặc ngôn ngữ đang thịnh hành chưa chắc đã phù hợp”
    • Rust về bản chất là một lựa chọn thay thế cho C++
      Nếu bạn chấp nhận được garbage collector thì không cần dùng Rust hay C++ để phải bận tâm đến quản lý bộ nhớ. Có người quảng bá Rust như một ngôn ngữ lập trình đa dụng, và về mặt lý thuyết điều đó là đúng, nhưng C++ những năm 90 cũng từng được quảng bá như vậy. Việc tối thiểu hóa cấp phát bộ nhớ thường chính là đặc tính mà người ta mong muốn khi chọn Rust hoặc C++
  • Rất khó để viết nhanh một ứng dụng web lớn bằng Rust
    Một ứng dụng lớn viết bằng Rails có thể không chạy nhanh, có thể nhiều lỗi, hoặc khó bảo trì và mở rộng. Các lựa chọn như Java, C#, Go có thể không sexy hay trông ngầu, nhưng vẫn có thể hoàn thành công việc nhanh gần như Rails trong khi chạy với tốc độ gần Rust. Thông thường chúng cũng ít lỗi hơn, và dự án sẽ dễ bảo trì cũng như mở rộng hơn

    • Không thể nghiêm túc nói rằng một ngôn ngữ hệ thống cấp thấp như Go lại có năng suất ngang Rails, một framework cấp cao cho ứng dụng CRUD
      Dù bạn có ghét Rails đến đâu đi nữa, điều này cũng giống như nói rằng có thể làm blog nhanh hơn WordPress bằng C++
    • Tôi cho rằng câu “một ứng dụng lớn viết bằng Rails thì không nhanh, nhiều lỗi, khó bảo trì và mở rộng” là một sự khái quát hóa quá mức
      Nếu được xây dựng cẩn thận thì không nhất thiết phải như vậy. Tôi đã thấy nhiều ứng dụng Rails lớn, gần như không có lỗi, ổn định và dễ chỉnh sửa, và cũng đã thấy cả ứng dụng Rails lẫn Go rất tệ. Một số ngôn ngữ hay framework có thể khiến người ta dễ rơi vào tình trạng đó hơn, nhưng cái gì cũng có khả năng như vậy, đồng thời luôn có những đánh đổi khiến nó khó ở những khía cạnh khác. Nếu có kỷ luật thì cái gì cũng có thể vận hành tốt
    • Ngay cả với Rails, vẫn có thể xây dựng ứng dụng quy mô lớn nhanh, ít lỗi, không quá khó bảo trì và mở rộng. Có rất nhiều ví dụ thực tế
      Với các lập trình viên có trình độ tương đương, Rails trong phần lớn tính năng ứng dụng web thường được phát triển nhanh hơn Java, C#, Go. Theo kinh nghiệm của tôi thì có khi nhanh hơn tới 3 lần. Tôi đã làm cả với monolith lớn lẫn kiến trúc hướng dịch vụ, và cũng từng làm cùng các nhóm Java. Có thời điểm tôi còn đưa Go vào một tổ chức Rails vì từng tin điều tương tự
      Cuối cùng, vấn đề thực sự là MVC không phù hợp với mọi thứ, và chúng tôi đã không dùng namespace đủ chặt chẽ. Nếu khắc phục điều đó trong những phạm vi nhỏ và có mục tiêu, Rails vẫn hoàn toàn ổn
    • Tôi chưa từng dùng Basecamp, nhưng tin rằng sản phẩm này được viết tốt và khá ổn
      Vì vậy, tôi cho rằng với đủ mức độ quản lý, kiến trúc tốt và bảo trì phù hợp thì Rails vẫn làm được
  • Gần đây tôi bắt đầu thử AdonisJS như một lựa chọn thay thế TypeScript cho Rails
    Nếu bạn quan tâm đến “Rails viết bằng TypeScript” thì nên thử một lần. Nó cho cảm giác gần với Rails hoặc Laravel hơn rất nhiều so với các stack TypeScript phổ biến nhất, và theo kiểu kèm sẵn đầy đủ thay vì bắt bạn phải tự chọn mọi phần của stack hoặc tin vào template bên thứ ba

    • Tôi đã tò mò về AdonisJS, và nhờ bình luận này mà tôi nghĩ mình sẽ thử nó
      Gần đây tôi bị thu hút bởi các backend framework kiểu kèm sẵn đầy đủ như Rails, Laravel, Django, nhưng vì gần như suốt sự nghiệp tôi đều dùng TypeScript nên cứ tiếp tục như hiện tại có lẽ dễ hơn là chuyển sang thứ khác. Tôi tò mò không biết cảm nhận của bạn sau khi thử ra sao, và liệu có thể so sánh nó với những framework khác mà bạn đã nhắc tới không
    • Tôi định thử AdonisJS, nên đây là tin tốt
      Gần đây trong các dự án cá nhân tôi đã chọn NestJS, nhưng rồi sớm biết đến Adonis và đang cân nhắc có nên chuyển hẳn sang không
  • Lý do các công nghệ như Next.js và SvelteKit phổ biến trong giới lập trình viên JavaScript là vì chúng giúp giảm bớt vấn đề trải nghiệm phát triển backend trên Node.js không tốt
    Xây backend bằng TypeScript khá giống xây bằng C#, nhưng lại có cảm giác thiếu đi những ưu điểm của một ngôn ngữ được thiết kế bài bản. Nó rất khác với trải nghiệm làm backend bằng Rails. Các lập trình viên Node.js cũng đang bắt đầu nhận ra rằng vấn đề không chỉ nằm ở hệ sinh thái và công cụ, mà framework cung cấp một lời giải tổng thể cho việc xây dựng ứng dụng mới là điều quan trọng. Phần mà Next.js và SvelteKit hỗ trợ chính là chỗ đó, và đó cũng là điều Rails đã cách mạng hóa từ năm 2006

    • Tôi thích TypeScript. Tôi tò mò không biết khi so với C# thì những điểm nào khiến nó không phải là một ngôn ngữ được thiết kế bài bản
    • So sánh Next.js hay Remix với Rails, Django, Laravel là khá khiên cưỡng
      Ý là chỉ vì nó có thể chạy code ở backend rồi đem ra so với Rails sao? Hỗ trợ truy cập cơ sở dữ liệu, migration, ORM, queue, tác vụ định kỳ, validation, i18n, authentication, authorization ở đâu? Thứ duy nhất Next.js giúp là đẩy mọi người vào nền tảng Vercel
    • Nếu phải chọn giữa C# và TypeScript thì cho backend tôi sẵn sàng chọn C#
      Còn với frontend thì tôi thích TypeScript hơn JavaScript
  • Mình hơi bối rối trước những bình luận cho rằng Rust không hợp lắm với web backend
    Khi chủ yếu làm các dịch vụ nhỏ như beampaint.com hay probablyup.net, mình lại có trải nghiệm ngược lại. Có thể khi xây dựng ứng dụng lớn hơn thì độ phức tạp sẽ tăng mạnh, và có lẽ chắc là vậy, nhưng Rust rất giỏi trong việc mang lại sự tự tin cần thiết cho các codebase lớn

    • Chẳng phải độ khó sẽ tăng vọt vào lúc bắt đầu cần nhiều tính năng thuộc phạm vi framework hơn sao?
      Các framework lâu đời có sẵn những thứ đó như mặc định, còn framework Rust thì do tuổi đời nên khả năng có đủ là thấp hơn. Cứ tưởng tượng số tính năng còn thiếu tăng từ hai lên sáu là được
  • Bài này gần như là câu chuyện đời mình
    Mình từng dùng Rails rồi đến năm 2013 ra mắt một ứng dụng SaaS viết bằng Go, và phải tự mày mò mọi thứ. Migration, tầng cơ sở dữ liệu, asset pipeline, triển khai, kiểm thử hợp lệ, ghi log, thanh toán... Rails có quá nhiều thứ được cung cấp sẵn

    • Dù vậy, rất có thể chính trải nghiệm đó đã giúp mình trở thành một lập trình viên thành thạo hơn
    • Đang so sánh một ngôn ngữ lập trình cấp thấp thiên về hệ thống, gần như chỉ có bộ khung, với một framework cấp rất cao chạy trên một ngôn ngữ cấp rất cao
      Mình không thích Go, nhưng ở đây thứ đáng bị trách không phải là Go. Dùng Go cho ứng dụng CRUD ngay từ đầu đã là một quyết định khủng khiếp
  • Django cũng cho cảm giác tương tự
    Các vấn đề hiệu năng thường phát sinh do truy vấn cơ sở dữ liệu hơn là từ chính Django

    • Gần như lúc nào truy vấn cơ sở dữ liệu cũng sẽ tốn thời gian nhất, nhưng mình đã thấy quá nhiều kỹ sư thậm chí còn không làm những tối ưu cơ bản như tạo chỉ mục
      Những tối ưu đơn giản nhưng hay bị quên gồm có: tạo chỉ mục cơ sở dữ liệu, đẩy nhiều logic sang cơ sở dữ liệu hơn thay vì để trong code, ví dụ dùng pipeline của MongoDB hoặc partial index của Postgres, bật nén Brotli/zstd cho hầu hết request, cache object hoặc request bằng bộ nhớ đệm như Redis, và đặt các header kiểm soát cache phù hợp. Ở frontend cũng cần các tối ưu như dùng canvas thay vì render hàng nghìn đối tượng thành DOM node. Gần đây mình đã thấy vấn đề này trong một ứng dụng bản đồ