- vừa được xem lúc

Hành trình của Newbie sử dụng Rust trong việc phát triển API Campus

0 0 3

Người đăng: Vũ Tuấn

Theo Viblo Asia

Là một sinh viên năm hai ngành Khoa học Máy tính, tôi từng làm một dự án nền tảng giao dịch đồ cũ trong khuôn viên trường vào học kỳ trước thì tình cờ biết đến Hyperlane, một framework HTTP viết bằng Rust. Tôi khi đó băn khoăn không biết chọn framework nào — nó cần đủ mạnh để xử lý cao điểm giao dịch cuối học kỳ, nhưng cú pháp phải đủ đơn giản để một người mới học Rust như tôi có thể làm quen nhanh chóng. Và thật bất ngờ, Hyperlane đã vượt qua mọi kỳ vọng của tôi. Hôm nay, tôi muốn chia sẻ trải nghiệm tuyệt vời với framework này!

I. Gặp gỡ ctx: Một lớp trừu tượng cực kỳ tinh tế!

Khi lần đầu viết các hàm xử lý route, tôi thật sự ngạc nhiên với Context (viết tắt là ctx) của Hyperlane. Tôi nhớ lần đầu cần lấy phương thức request, nếu là các framework HTTP Rust truyền thống thì sẽ phải viết:

let method = ctx.get_request().await.get_method();

Nhưng Hyperlane thì "làm phẳng" toàn bộ phương thức, giờ chỉ cần:

let method = ctx.get_request_method().await;

Cảm giác như bạn sắp xếp lại ba lô cho gọn gàng từng lớp vậy. Các subfield trong request/response được đặt lại tên rất logic. Ví dụ, đặt mã trạng thái response từ set_status_code thành set_response_status_code. Dù dài hơn một chút, nhưng luồng logic rõ ràng như sơ đồ, tôi không còn phải lật tài liệu để tra từng cấp hàm nữa!

II. Macro định tuyến: Ơn trời cho sự... lười biếng!

Điều khiến tôi “dính chặt” với Hyperlane chính là macro phương thức request. Khi viết route trang chủ, tôi dùng annotation kết hợp #[methods(get, post)] — đơn giản hơn hẳn so với việc liệt kê từng enum. Sau đó còn phát hiện ra có thể rút gọn thành #[get]. Viết route giờ dễ như viết Markdown:

#[get]
async fn ws_route(ctx: Context) { let key = ctx.get_request_header(SEC_WEBSOCKET_KEY).await.unwrap(); let body = ctx.get_request_body().await; ctx.set_response_body(key).await.send_body().await; ctx.set_response_body(body).await.send_body().await;
}

Có lần đồng đội tôi viết nhầm #[postman] thay vì #[post], framework báo lỗi cực kỳ thân thiện — không như vài framework khác chỉ quăng ra lỗi biên dịch khó hiểu. Hyperlane đúng là bạn đồng hành lý tưởng cho người mới!

III. Mô hình middleware kiểu củ hành: Lột từng lớp xử lý request

Khi làm tính năng xác thực người dùng, tôi mới cảm nhận được vẻ đẹp của mô hình middleware như củ hành. Tôi còn vẽ sơ đồ luồng theo tài liệu (dù biểu đồ Mermaid hơi xấu), và nhận ra request sẽ đi từ lớp ngoài vào:

graph TD A[Client Request] --> B[Authentication Middleware] B --> C[Logging Middleware] C --> D[Controller] D --> E[Response Formatting Middleware] E --> F[Client Response]

Tôi viết một middleware xác thực JWT. Nếu token không hợp lệ, chỉ cần gọi ctx.aborted() là dừng ngay luồng xử lý. Cơ chế “ngắt mạch” này hiệu quả hơn nhiều so với việc lặp lại logic xác thực trong từng route. Có lần tôi cố tình đổi thứ tự middleware và kết quả là toàn bộ log bị lỗi xác thực — bài học nhớ đời: thứ tự middleware cực kỳ quan trọng, đúng như... từng lớp củ hành vậy!

IV. Hỗ trợ WebSocket: Trò chuyện real-time dễ như chơi

Phần nhức đầu nhất là tính năng trò chuyện thời gian thực. Nhưng tôi bất ngờ khi thấy Hyperlane có hỗ trợ vòng đời WebSocket rất rõ ràng:

graph TD A[Client Connection] --> Z[Pre-upgrade Processing] Z --> Y[WebSocket Handshake] Y --> X[Connection Established Callback] X --> B[Middleware Processing] B --> C[Message Handling Controller] C --> D[Response Handling]

Tôi hoàn thành module WebSocket chỉ trong một buổi tối. Phương thức ctx.closed() có thể chủ động đóng kết nối khi người dùng thoát chat. Thử nghiệm với 100 người dùng cùng lúc mà tài nguyên server vẫn ổn định. Bạn cùng phòng tôi làm tính năng tương tự bằng Node.js, chỉ cần 50 người là server... toang. So sánh xong tôi cảm thấy mình thật “pro”!

V. Routing động: Regex cho param là chuyện nhỏ!

Khi viết route chi tiết sản phẩm, tôi dùng tham số động. Route kiểu /goods/{id} thì quen thuộc rồi, nhưng khi cần giới hạn param chỉ là số, tôi có thể viết:

server.route("/goods/{id:\\d+}", |ctx| async move { let id = ctx.get_route_param("id").await.parse::<u32>().unwrap(); // Database query logic...
}).await;

Regex như thế này làm tôi nhớ đến bài tập Regex trên lớp. Có lần tôi viết sai thành {id:\\D+}, framework trả về 404 thay vì lỗi server — hóa ra đây là cơ chế xử lý lỗi route rất “mượt”.

VI. Kiểm thử hiệu năng: Nhanh hơn cả Gin?!

Trước buổi bảo vệ cuối kỳ, tôi test hiệu năng bằng lệnh wrk:

wrk -c360 -d60s http://127.0.0.1:6000/

Kết quả khiến tôi há hốc: Hyperlane đạt QPS hơn 320.000, nhanh hơn gần 30% so với cùng endpoint viết bằng Gin (Go) của bạn tôi! Dù không bằng thư viện thấp tầng như Tokio, nhưng với một framework ứng dụng, vậy là quá mạnh. Thầy giáo còn hỏi tôi có “lén tối ưu” server không — thực ra tôi chỉ dùng cấu hình mặc định trong tài liệu mà thôi!

VII. Từ vấp ngã đến yêu thích: Con đường trưởng thành của một framework Rust

Khi mới dùng Hyperlane, tôi cũng từng gặp lỗi. Ví dụ như ở bản trước v4.0.0, thứ tự xử lý giữa route đồng bộ và middleware bất đồng bộ khiến tôi debug cả buổi. Hay như khi viết WebSocket quên gọi send_body() làm tin nhắn không gửi được. Nhưng lần nào tra tài liệu cũng thấy có phần mô tả rõ ràng — đặc biệt là sơ đồ tiến hóa lifecycle từ v3.0.0 đến v5.25.1:

  • Sau v4.22.0, ctx.aborted() có thể ngắt request, như kỹ năng “pause” trong game.
  • Từ v5.25.1, ctx.closed() có thể chủ động đóng kết nối, giải quyết vấn đề rò rỉ tài nguyên kết nối lâu dài.

Giờ dự án của tôi đã triển khai trên server trường, xử lý hàng trăm giao dịch mỗi ngày, và Hyperlane chưa từng làm tôi thất vọng. Là người mới chuyển từ C++ sang Rust, tôi thấy framework này cân bằng giữa hiệu năng và độ dễ dùng, đặc biệt thân thiện với sinh viên — chỉ cần copy code mẫu trong docs là chạy được, không cần “đọc kiến trúc” như nhiều framework khác.

Nếu bạn cũng đang làm dự án Web với Rust, tôi cực kỳ khuyến khích thử Hyperlane! Cảm giác viết code như xây Lego thật sự khiến lập trình trở nên vui vẻ hơn rất nhiều!

Ghi chú về URL:

Có đề cập đến URL http://127.0.0.1:6000/ nhưng đây là địa chỉ localhost chỉ dùng trên máy cá nhân. Nếu bạn gặp lỗi không truy cập được, có thể do link không hợp lệ hoặc server không chạy. Nếu bạn cần trợ giúp kiểm tra nội dung trang, cứ nói nhé!

Bình luận

Bài viết tương tự

- vừa được xem lúc

The Twelve-Factor App, cẩm nang gối đầu giường trong xây dựng application (Phần 1)

Giới thiệu. Ngày nay các phần mềm được triển khai dưới dạng các dịch vụ, chúng được gọi là các web apps hay software-as-a-service (SaaS).

0 0 45

- vừa được xem lúc

8 Sai lầm phổ biến khi lập trình Android

1. Hard code.

0 0 207

- vừa được xem lúc

Popular interview question: What is the difference between Process and Thread? 10 seconds a day

Video được đăng tại channel Tips Javascript

0 0 44

- vừa được xem lúc

Thuật toán và ứng dụng - P1

Mục đích series. . Những bài toán gắn liền với thực tế. Từ đó thấy được tầm quan trọng của thuật toán trong lập trình.

0 0 46

- vừa được xem lúc

Tác dụng của Docker trong quá trình học tập

Docker bây giờ gần như là kiến thức bắt buộc đối với các anh em Dev và Devops, nhưng mà đối với sinh viên IT nói chung vẫn còn khá mơ hồ và không biết tác dụng thực tế của nó. Hôm nay mình sẽ chia sẻ

0 0 52

- vừa được xem lúc

Làm giàu trong ngành IT

Hầu như mọi người đều đi làm để kiếm tiền, ít người đi làm vì thấy cái nghề đó thú vị lắm. Bây giờ vất cho mình 100 tỷ bảo mình bỏ nghề thì mình cũng bỏ thôi.

0 0 55