Blog
November 25, 2023

Sử dụng Elixir Phoenix trong một dự án SaaS thương mại

Linkly được viết bằng Elixir.

Tôi luôn muốn tiếp xúc với hệ sinh thái Erlang, và Elixir là một lộ trình dễ dàng.

Tôi sẽ không đề cập đến những lợi ích của BEAM hoặc Erlang trực tiếp tại đây, vì điều đó đã được viết ở những nơi khác. Thay vào đó, tôi sẽ tập trung vào các khía cạnh thực tế của việc sử dụng Elixir Phoenix cho một dự án thực tế.

Tôi sẽ giả định rằng bạn biết Ruby on Rails là gì, vì Phoenix, web framework của Elixir, được lấy cảm hứng từ Rails.

Lập trình thực tế trong Elixir Phoenix

Lập trình trong Elixir là một trải nghiệm vui vẻ.

Nó tuân theo các mô hình tương tự như Rails, bao gồm MVC, và thậm chí có vẻ tương tự.

Không giống như Rails, mã được biên dịch trước khi chạy. Đây là một bước hữu ích vì nó cho phép bạn bắt các lỗi mà nếu không bạn có thể không phát hiện được.

Các Models trong Phoenix được nhóm thành 'Contexts'. Đây là một cấp độ trừu tượng hóa bổ sung, nhằm tạo ra sự phân tách rõ ràng giữa các phần của ứng dụng, ví dụ: Users và Products. Mỗi context có thể chứa bất kỳ số lượng models nào.

Hiệu suất

Rất nhiều điều đã được nói về hiệu suất trên các blog khác, vì vậy tôi sẽ đề cập đến khía cạnh thực tế ở đây.

Đối với một web framework đầy đủ các tính năng, hiệu suất rõ ràng nhanh hơn nhiều so với Rails, và yêu cầu phần cứng ít hơn đáng kể để chạy.

Thời gian 'khởi động' của việc chạy mix phx.server so với rails server nhanh hơn. Thậm chí khi phát triển trên laptop, các trang tải nhanh hơn đáng kể với Phoenix.

Tính sẵn có của các gói cho Elixir Phoenix so với Rails

Bề ngoài, có vẻ như có sự khác biệt ở đây. Rails có hàng nghìn gems so với kho lưu trữ Hex của Elixir.

Hóa ra, gần như mọi thứ bạn thực sự sử dụng đều có sẵn trong hệ thống gói Hex của Elixir - trình phân tích cú pháp JSON, máy khách HTTP, công cụ để định dạng và phân tích cú pháp Markdown - tất cả đều có ở đó, và chất lượng mô-đun là xuất sắc.

Trong Rails, có nhiều gems hơn đáng kể, nhưng bạn sẽ không bao giờ đưa chúng vào một dự án thực tế, do trạng thái không được bảo trì hoặc rủi ro liên quan đến việc xây dựng quá nhiều phụ thuộc bên ngoài vào ứng dụng của bạn.

Các nền tảng như Stripe và Recurly duy trì các gems Rails của riêng họ để tương tác với API của họ. Điều này có thể tiện lợi, và thường thiếu hỗ trợ cho Elixir.

Tuy nhiên, tôi thấy rất dễ dàng sử dụng gói Tesla của Elixir để tương tác với các điểm cuối HTTP của các dịch vụ, và cuối cùng đã thích làm việc theo cách này hơn, so với việc sử dụng các gems được đóng gói sẵn, vì nó nhẹ hơn và cho phép bạn hiểu những gì đang xảy ra.

Trừu tượng cơ sở dữ liệu - Ecto và ActiveRecord

Ecto không đầy đủ tính năng như ActiveRecord.

Nó không được dự định như vậy.

Ecto là một trình bao bọc cơ sở dữ liệu đơn giản ánh xạ các truy vấn cơ sở dữ liệu đến các đối tượng Elixir.

Ban đầu, tôi cảm thấy nó khó chịu vì nó không hoạt động giống như ActiveRecord.

Tuy nhiên, Ecto cho phép bạn tương tác với cơ sở dữ liệu một cách rất đơn giản, và thực sự giúp lập trình các ứng dụng web dễ dàng hơn nhiều.

Với ActiveRecord, khi bạn bắt đầu xây dựng các truy vấn phức tạp, việc tìm hiểu ActiveRecord mất nhiều thời gian hơn chỉ viết một truy vấn dưới dạng SQL.

Đã sử dụng cả hai, kết luận của tôi là sử dụng một trình bao bọc cơ sở dữ liệu nhẹ như Ecto dễ dàng hơn so với sử dụng một trừu tượng nặng như ActiveRecord.

Nó cung cấp cho bạn sự an toàn của việc sử dụng một trình bao bọc cơ sở dữ liệu, mà không có sự phiền toái và gánh nặng của một trừu tượng "quá thông minh".

Cả hai đều chứa chức năng migration và rollback.

Cơ sở dữ liệu mặc định cho các dự án Phoenix là Postgres.

Đối với những người sử dụng cơ sở dữ liệu NoSQL, Ecto hoạt động với Mongo.

Tốt hơn nữa, Ecto hoạt động với các tính năng NoSQL của Postgres, cho phép bạn lưu và truy vấn JSON mà không cần Mongo.

Xác thực người dùng

Đây là nơi Elixir Phoenix thiếu.

Rails có mô-đun Devise. Phoenix có Coherence, tuy nhiên nó hiện không được bảo trì.

Nếu bạn muốn sử dụng đăng nhập tên người dùng & mật khẩu cơ bản, bạn sẽ phải xây dựng từng bước của nó. Điều đó bao gồm mã hóa mật khẩu, logic đặt lại mật khẩu, cài đặt 'remember-me' v.v.

Điều này rất tẻ nhạt và mang theo rủi ro bảo mật đáng kể.

Tôi chọn sử dụng Auth0, hoạt động tốt với Phoenix. Có thể đây là một giải pháp tốt hơn, nhưng sẽ rất tốt nếu có lựa chọn.

Triển khai & Lưu trữ

Máy chủ chính của các ứng dụng Phoenix là Gigalixir, một công ty nhỏ của Mỹ được điều hành bởi những người đam mê Elixir.

Gigalixir được lưu trữ trên Google Cloud, vì vậy cơ sở hạ tầng cơ bản là vững chắc.

Buildpack của Gigalixir làm cho việc triển khai dễ dàng, và hỗ trợ tất cả các chiến lược triển khai thông minh của Elixir (distillery, mix).

Nó đắt hơn 'tự làm', nhưng phần lớn chi phí được gói gọn trong lưu trữ cơ sở dữ liệu Postgres.

Elixir Phoenix rất nhẹ nên nó có thể chạy trên các pod docker nhỏ và vẫn có thể xử lý một số lượng yêu cầu rất khỏe.

Mặc dù đánh dấu, nhưng nó hoàn toàn đáng để loại bỏ phiền toái.

Tôi chỉ muốn thêm rằng hỗ trợ khách hàng của họ là xuất sắc.

Tính sẵn có của các lập trình viên

Có ít lập trình viên Elixir hơn đáng kể.

Elixir là "ngôn ngữ của lập trình viên" - một ngôn ngữ mà mọi người đến, đã học cái gì khác.

Điều đó nói rằng, những người làm Elixir thường là những lập trình viên tốt hơn. Có thể đó là lựa chọn có ý thức của việc chọn một ngôn ngữ tốt hơn.

Nó khiến tôi nhớ đến những ngày đầu của Rails, khi có vẻ như chỉ những "rockstars" mới sử dụng nó (so với PHP).

Bất kỳ lập trình viên Rails giỏi nào cũng sẽ không gặp vấn đề gì khi học Elixir Phoenix, và sẽ chạy trong vòng vài ngày.

Liệu tôi có sử dụng Elixir Phoenix lại không?

Chắc chắn.

Tôi đã làm việc với rất nhiều ngôn ngữ, và Elixir là ngôn ngữ dễ dàng và mạnh mẽ nhất mà tôi đã làm việc.

Tôi mong chờ để viết Elixir.

Nhận ngay 100 liên kết rút gọn và theo dõi 500 lượt nhấp chuột mỗi tháng hoàn toàn miễn phí.