Tạp chí Thợ Code

Xây dựng Serverless API với AWS API Gateway, Lambda (Nodejs), MongoDB Atlas

Ban biên tập chúng tôi vừa nhận được được bản nháp tài liệu thiết kế kiến trúc và hướng dẫn chi tiết xây dựng hệ thống API đảm bảo tính linh hoạt, tiết kiệm, bảo mật và khả dụng và dễ dàng tích hợp. Vì quá dài nên chúng tôi cứ thế mà đăng tải, mời quý bạn đọc thưởng thức.

Bối cảnh

Cấp Cao Chiên Da được chủ tạch Tập đoàn Toàn Đập Đá giao nhiệm vụ trong một tuần phải xây dựng xong hệ thống quản lý thông tin thiết bị để phục vụ công tác chào mừng đại lễ kỷ niệm sắp tới.

Hệ thống khá phức tạp với nhiều thành phần công nghệ khác nhau, trong đó có một module cần một API nho nhỏ để gọi lấy thông tin là chính, việc cập nhật thông tin cũng cần nhưng không cần tức thì, chủ yếu dùng cho việc thống kê vào cuối ngày là chính.

GET, OPTIONS api.tapdoantoandapda.com/device-detail/?id=xxx

POST api.tapdoantoandapda.com/device-detail

GET api.tapdoantoandapda.com/device-pinout/?id=xxx

Với nhu cầu đó Chiên Da quyết định sẽ sử dụng Mongo Altlas gói miễn phí, vì cũng không có mấy endpoint và tính năng đơn giản nên sẽ sử dụng công nghệ Lambda serverless cộng với API Gateway (API GTW) để expose API này ra ngoài Internet. Ở ngay chỗ API GTW đã có tính năng cache và custom domain “có vẻ” đủ xài rồi nhưng với tiêu chí phục vụ chủ tịch là nhiệm vụ của mình, còn trả tiền bill cloud thì là của chủ tịch nên Chiên Da đã quyết định bổ sung thêm CloudFront là lớp cuối cùng để giao tiếp với end-user, qua đó có thể dễ dàng control cache cũng như là sử dụng alias domain được quản lý ở Route 53.

画像が読み込まれない場合はページを更新してみてください。

Nhân những ngày uể oải đợi nghỉ lễ sắp tới, à không, nhân những ngày sục sôi không khí nhà nhà thi đua số lượng line of code, người người thi đua tìm và bắt bug nên tôi đã dành chút thời gian để viết lại quá trình xây dựng hệ thống này trước là để sau này lỡ có phải nhìn lại code của chính bản thân thì cũng bớt chút cảm giác lạ lẫm sau là để cho quý anh chị em nào có cần thiết thì hãy sử dụng. Tôi rất lấy làm hân hạnh vì đều này, mong rằng sẽ hữu ích và giúp quý anh chị em có thêm được thời gian để sống cuộc đời bên ngoài màn hình. (Đây là đoạn tự sự của Chiên Da, tác giả bài viết -LTS).

MongoDB Atlas

Ở thời điểm viết bài này MongoDB cho phép sử dụng Shared Cluster với dung lượng lưu trữ 512MB ở trên cả 3 cloud provider AWS/ Azure/ GCP. Bạn có thể xem chi tiết tại https://www.mongodb.com/pricing.

Lambda Function

File app.mjs của mình sẽ như bên dưới

File hỗ trợ kết nối MongoDB Atlas

Vì đặc trưng của Lambda function thì sẽ thực thi trong hàm handler nên mình sẽ xây dựng thêm hàm handleRequest để xử lý các endpoint nhận được theo đúng các method. Với 3 method ở trên, mình thử nghiệm chạy tốn khoảng 105MB memory.

Trong source code, mình có sử dụng package mongosee nên cần phải chạy npm install [package-name] trên máy local rồi sau đó zip luôn cả folder node_modules để upload lên Lambda. Không rõ ngay đây có cách nào thao tác hay hơn không.

Thật ra thì nếu chỉ cần làm MVP hay demo cho sếp coi thì tới đây cũng là đủ rồi vì Lambda cho phép expose một HTTPS URL (Enable function URL) với đầy đủ các tính năng cơ bản vốn có của một API như:

  • Auth type: sử dụng AWS_IAM hoặc public
  • Invoke mode:
  • Configure cross-origin resource sharing (CORS): có thể tự cấu hình lại các origin, expose headers, allow headers, allow methods, max age.

Tuy nhiên vì hạn chế lớn nhất của Function URL là mỗi URL chỉ trỏ được đến đúng 1 version hoặc alias thôi, không thể thay đổi được giá trị trỏ đến nên sẽ rất khó để quản lý và sử dụng thực tế, ở môi trường cần sự ổn định ít thay đổi các giá trị cấu hình.

API Gateway (API GTW)

API GTW sẽ giải quyết câu chuyện Function URL ở trên, cũng tại màn hình Function overview của Lambda, ta bấm Add trigger để tiến hành chọn API GTW từ trong source của Trigger configuration.

画像が読み込まれない場合はページを更新してみてください。

Làm vầy thì tiện nhưng cái API url tạo ra đều bị đính kèm thêm một đoạn tên của Lambda Function, khá bất tiện thế nên chúng ta sẽ chọn giải pháp tự tạo API GTW riêng.

Từ màn hình API GTW Console bấm nút Create API > Choose an API type > REST API > Build. Ở màn hình tiếp theo ta chỉ cần điền API name, còn lại mọi thứ để như mặc định.

画像が読み込まれない場合はページを更新してみてください。

Chọn Actions > Create Resource để tạo một nhóm resource, nhóm này sẽ chứa các endpoint. Chỗ này thì nhớ chọn Enable API Gateway CORS, với tùy chọn này thì sau khi tạo xong sẽ mặc định có endpoint method OPTIONS phục vụ cho việc preflight (một phương pháp để kiểm tra xem browser có quyền truy cập vào tài nguyên đích không).

画像が読み込まれない場合はページを更新してみてください。

Tiếp tục chọn Actions > Create Method, chọn method click nút check kế bên sau đó điền Lambda Function, nhớ chọn Use Lambda Proxy integration để request package gửi lên được nhét vào event theo đúng cấu trúc code ở Lambda ở trên.

画像が読み込まれない場合はページを更新してみてください。

Sau khi xong lại chọn Actions > Deploy API, hoàn tất bạn sẽ thấy màn hình production Stage Editor với Invoke URL.

画像が読み込まれない場合はページを更新してみてください。

Đến đây xem như cơ bản đã hoàn thành và có thể đưa vào sử dụng.

Anh Dũng

Sài Gòn những ngày nhiều mưa, tháng 09/ 2023.