Xây dựng RestAPI theo mô hình Serverless

Xây dựng RestAPI theo mô hình Serverless

  • Kai
  • August 23, 2024

Xin chào tất cả các bạn, lại là mình đây. Hôm nay mình sẽ chia sẻ một kiến trúc được xây dựng theo mô hình serverless. Mô hình này mình sẽ viết dựa trên Django Rest Framework. Đây là một framework mình rất ưa thích và đã sử dụng nhiều trong các dự án của mình. Và mình sẽ sủ dụng một số dịch vụ của AWS như Route 53, API Gateway, Lambda, ECR, và AWS Certificate Manager để thực hiện trong bài blog này.

I. Tổng quan

Kiến trúc Serverless (hay không máy chủ) là một mô hình điện toán đám mây, nơi mà nhà phát triển không phải quản lý máy chủ. Thay vào đó, mọi thứ được vận hành bởi các dịch vụ quản lý tự động của nhà cung cấp đám mây (AWS), giúp giảm bớt gánh nặng về vận hành.

Với việc sử dụng Serverless, bạn sẽ có được những ưu điểm gì?

  • Tự động mở rộng (Auto-scaling): Hệ thống sẽ tự động điều chỉnh tài nguyên để đáp ứng lưu lượng truy cập, bất kể lượng truy cập đó lớn hay nhỏ. Điều này giúp ứng dụng của bạn luôn hoạt động ổn định mà không cần lo lắng về việc nâng cấp hay điều chỉnh cơ sở hạ tầng.
  • Tiết kiệm chi phí (Pay-per-use): Bạn chỉ phải trả tiền cho những tài nguyên thực sự được sử dụng, chẳng hạn như số lượng yêu cầu API hoặc thời gian thực thi của Lambda function. Điều này giúp tối ưu hóa chi phí, đặc biệt là đối với các ứng dụng có lưu lượng không đều.
  • Giảm thiểu gánh nặng quản lý (No server management): Bạn không cần phải quản lý, duy trì hoặc cập nhật máy chủ. AWS sẽ đảm nhận toàn bộ việc này, giúp bạn tập trung hơn vào việc phát triển và cải tiến ứng dụng.
  • Tích hợp mạnh mẽ với các dịch vụ khác: Serverless thường tích hợp tốt với nhiều dịch vụ đám mây khác, như cơ sở dữ liệu, lưu trữ, và dịch vụ AI/ML, giúp bạn xây dựng các ứng dụng toàn diện mà không cần phải kết hợp nhiều công nghệ khác nhau.

Những ưu điểm này giúp Serverless trở thành một lựa chọn hấp dẫn cho việc xây dựng các ứng dụng hiện đại, đặc biệt là khi bạn cần một hệ thống linh hoạt, tiết kiệm chi phí và dễ dàng quản lý.

Tiếp theo ta sẽ đi sâu vào trong kiến trúc mà mình sẽ xây dựng, các phần chuẩn bị cụ thể nào.

II. Chuẩn bị

1. Đăng ký Route 53

Trong bước này, chúng ta sẽ đăng ký một domain trên Route 53 để sử dụng cho bài Lab. Sau đó mình sẽ cung cấp một source được viết bằng Django - Python để tiến hành thực hành trong bài lab này.

Để tìm hiểu cách chi tiết về Route 53 thì các bạn có thể tham khảo tài liệu của AWS sau:

  1. Truy cập giao diện console
  • Tìm kiếm Route 53.
  • Chọn Route53.
alter-text
Màn hình console AWS.
  1. Tại trang Route 53.
  • Nhập domain bạn muốn đăng ký vào mục Register Domain, nhấn Check.
  • Hoặc nhấn chọn tại Domain > Registered Domains.
  • Trong trang Registered Domains nhấn chọn Register Domain.

alter-text
Giao diện Route 53.
alter-text
Đăng ký domain.

  1. Tại trang Register Domains.
  • Nhập domain bạn muốn đăng ký vào mục Check availability for a domain, nhấn Search để tìm kiếm.
  • Chọn Select vào domain bạn muốn đăng ký sau đó nhấn Proceed to checkout.
alter-text
Thông tin đăng ký domain.
  1. Tại trang Checkout.
  • Xác nhận thông tin domain của bạn, sau đó chọn Duration chọn từ 1-10 năm.
  • Nếu bạn muốn Auto-renew thì click chọn vào ô Auto-renew (Bạn vẫn có thể tắt tính năng này ở edit).
  • Tiếp theo điền các thông tin liên hệ cơ bản của bạn.
  • Cuối cùng là Review và nhấn Submit

alter-text
Lựa chọn giá theo Duration.
alter-text
Cung cấp thông tin người liên hệ của domain.
alter-text
Review và Submit.

  1. Tại trang Requests.
  • Bạn sẽ thấy những domain mà bạn đăng ký ở dưới đây, sau khi trừ tiền thanh toán (Domain sẽ không được xài Credit) thì requests sẽ là Successful, vậy là bạn sẽ có thể sử dụng được domain trong Route 53.
    alter-text
    Giao diện Route53.

2. Chuẩn bị Source Code

1. Source Code.

  • Để có thể thực hành trong bài Lab này thì mình đã chuẩn bị sẵn một source code được viết bằng Django - Python. Các bạn có thể clone về để thử nghiệp serverles-django-demo .

2. Giải thích về thư viện Mangum.

  • Mangum là một thư viện Python được thiết kế để hỗ trợ triển khai các ứng dụng ASGI (Asynchronous Server Gateway Interface) trên AWS Lambda. Thư viện này hoạt động như một bộ chuyển đổi, cho phép các ứng dụng ASGI xử lý các sự kiện từ nhiều dịch vụ AWS khác nhau, bao gồm API Gateway, Application Load Balancer (ALB) và Lambda@Edge. Điều này rất hữu ích cho các nhà phát triển muốn tận dụng kiến trúc serverless trong khi sử dụng các framework Python hiện đại như FastAPI, Starlette và Django. Quy trình xử lý sẽ được xử lý:
  • Nhận Sự Kiện từ API Gateway: Khi một yêu cầu HTTP được gửi tới API Gateway, nó sẽ tạo ra một sự kiện (event) chứa thông tin về yêu cầu đó, bao gồm phương thức HTTP, đường dẫn, headers, body, v.v. Sự kiện này sau đó được gửi tới Lambda function.
  • Chuyển Đổi Sự Kiện sang ASGI: Mangum nhận sự kiện này và chuyển đổi nó thành một yêu cầu theo chuẩn ASGI. Bao gồm Headers, Body, Path, Method.
  • Chuyển Đổi Phản Hồi (Response): Sau khi Django xử lý xong, một phản hồi (response) sẽ được tạo ra theo định dạng ASGI. Mangum sẽ nhận phản hồi này và chuyển đổi nó lại thành định dạng mà API Gateway yêu cầu, bao gồm
  • Gửi Phản Hồi về API Gateway: Cuối cùng, phản hồi đã được chuyển đổi này sẽ được gửi lại cho API Gateway, và từ đó, API Gateway sẽ trả phản hồi này về cho client (người dùng hoặc hệ thống đã gửi yêu cầu ban đầu).

3. Chuẩn bị Dockerfile

FROM public.ecr.aws/lambda/python:3.9
ADD . "${LAMBDA_TASK_ROOT}"
RUN  pip3 install -r "${LAMBDA_TASK_ROOT}"/req.txt --target "${LAMBDA_TASK_ROOT}"
# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD ["lambda_handler._handler"]
  • public.ecr.aws/lambda/python:3.9: Đây là base image được cung cấp bởi AWS, chứa môi trường runtime Python 3.9 và các công cụ cần thiết để chạy hàm Lambda trên nền tảng AWS Lambda.
  • Trong ngữ cảnh AWS Lambda và API Gateway, handler là điểm bắt đầu cho tất cả các sự kiện được gửi đến hàm Lambda. Khi một sự kiện (chẳng hạn yêu cầu HTTP từ API Gateway) xảy ra, AWS Lambda sẽ gọi đến handler được chỉ định. Vậy nên mình sẽ chỉ định đúng handler trong Docker Image này.

3. ECR

Trong bước này chúng ta sẽ tiến hành tạo ECR, sau đó sẽ tiến hành tạo ra image và đẩy lên ECR này để có thể sử dụng trong việc khởi tạo Lambda.

  1. Truy cập giao diện console
  • Tìm kiếm ECR.
  • Chọn ECR.
alter-text
Giao diện Console AWS.
  1. Tại trang ECR, nhấn chọn Create.
alter-text
Khởi tạo Repository.
  1. Tại trang Create Repository.
  • Ở dòng Visibility settings:

    • Private: Nếu bạn muốn repository của bạn là private
    • Public: Nếu bạn muốn repository của bạn là public
  • Ở dòng Repository name, điền tên của repository mà bạn muốn, ở đây mình sẽ điền django-serverless-demo

  • Ở dòng (Optional) Image scan settings:

    • Đây là tùy chọn cho phép bạn bật tính năng quét hình ảnh (image scanning) để kiểm tra các lỗ hổng bảo mật có thể có trong các image mà bạn đẩy lên repository. Nếu được bật, hệ thống sẽ tự động quét các image và đưa ra báo cáo về các lỗ hổng được phát hiện. Điều này rất hữu ích nếu bạn muốn đảm bảo an toàn cho các image trước khi sử dụng chúng trong môi trường sản xuất.
  • Ở dòng (Optional) Encryption settings:

    • Đây là tùy chọn cho phép bạn bật mã hóa cho các image được lưu trữ trong repository. Khi bật mã hóa, tất cả các image sẽ được mã hóa trước khi được lưu trữ, giúp bảo vệ dữ liệu khỏi các truy cập trái phép. Bạn có thể sử dụng khóa mã hóa do AWS quản lý hoặc tự quản lý khóa mã hóa của mình để kiểm soát bảo mật cao hơn.
  • Ở dòng (Optional) Tag Immutability:

    • Đây là tùy chọn cho phép bạn bật tính năng không thay đổi tag (tag immutability). Khi bật tính năng này, một khi một tag đã được gán cho một image, tag đó sẽ không thể được thay đổi hoặc gán lại cho một image khác. Điều này giúp đảm bảo tính toàn vẹn của các phiên bản image, tránh việc vô tình ghi đè hoặc thay đổi các image quan trọng đã được gán tag.
  • Sau khi lựa chọn xong thì nhấn Create Repository

    alter-text
    Khởi tạo repository.
    alter-text
    Khởi tạo repository.

  1. Nhấn vào Repository vừa tạo.
  • Nhấn chọn View push command để có thể xem cách push image lên repository
    alter-text
    Giao diện ECR.
    alter-text
    Giao diện ECR.
    alter-text
    Danh sách các command để push image.
  1. Mở Terminal tại Source Code.
  • Đầu tiên ta sẽ login vào repository của mình
aws ecr get-login-password --region ap-southeast-1 | docker login --username AWS --password-stdin <acoount-id>.dkr.ecr.ap-southeast-1.amazonaws.com
  • Tiếp theo ta sẽ tiến hành build image với câu lệnh sau. Đối với các bạn xài Mac M1 nhưng muốn chạy kiến trúc x86_64 thì mình sẽ thêm –platform linux/amd64.
docker build --platform linux/amd64 -t django-serverless-demo -f docker/DockerfileLambda .
  • Cuối cùng là đánh tag cho image và push lên ECR:
docker tag django-serverless-demo:latest <acoount-id>.dkr.ecr.ap-southeast-1.amazonaws.com/django-serverless-demo:latest
docker push <account-id>.dkr.ecr.ap-southeast-1.amazonaws.com/django-serverless-demo:latest  
alter-text
Route53.

Tiếp theo chúng ta sẽ thực hiện tạo Lambda & API Gateway.

III. Tạo Lambda & API Gateway

1. Tạo Lambda

  1. Tìm kiếm Lambda. Chọn Lambda.
alter-text
Giao diện Console AWS.
  1. Tại trang Lambda, nhấn chọn Create Function.
alter-text
Giao diện AWS Lambda
  1. Tại trang Create Function
  • Nhấn sang Tab Container Image.
  • Nhập tên Function vào mục Function name.
  • Tại mục Container Image URI, nhấn chọn Browse Image.
alter-text
Khởi tạo Function trong AWS Lambda.
  • Nhấn chọn Repository đã tạo lúc nãy “django-serverless-demo”.
  • Tick chọn Image phù hợp.
  • Nhấn Select Image để chọn Image này.
    alter-text
    Lựa chọn Container Image.
  • Tại mục Architecture, chọn kiến trúc phù hợp với Image của bạn. Khi nãy mình build x86 nên mình sẽ chọn x86.
  • Nhấn Create Function để khởi tạo Image.
    alter-text
    Khởi tạo Function trong AWS Lambda.
    alter-text
    Khởi tạo Function trong AWS Lambda.

Tiếp theo chúng ta sẽ khởi tạo API Gateway để Trigger Lambda này.

2. Tạo API Gateway

  1. Tìm kiếm API Gateway. Chọn API Gateway.
alter-text
Giao diện AWS Console.
  1. Tại trang API Gateway.
  • Kéo xuống dưới phần Choose an API type.
  • Chọn HTTP API, nhấn chọn Build.
alter-text
Khởi tạo API Gateway.
  1. Tại Step 1: Create an API.
  • Nhấn chọn Add integration.
  • Nhấn chọn Lambda, chọn Region ap-southeast-1, chọn Lambda Function, chọn Version 2.0.
  • Tại mục API name, nhập tên API name của bạn, sau đó bấm Next.
alter-text
Khởi tạo API Gateway
  1. Tại Step 2 Configure Routes
  • Phần Method, tiến hành chọn GET.
  • Phần Resource Path, tiến hành nhập /{proxy+}.
  • Phần Integration target, nhấn chọn lambda function.
  • Cuối cùng nhấn Next.
alter-text
Cấu hình Routes cho API Gateway
  1. Tại Step 3 Define Stages.
  • Tại phần Stage Name, chọn Stage của bạn, ở đây mình chọn stage mặc định là Default, cuối cùng là nhấn Next.
alter-text
Định nghĩa Stages cho API Gateway.
  1. Tại Step 4 Review and Create.
  • Tại phần này bạn review lại coi mình config chuẩn hết chưa.
  • Sau khi review thì nhấn Create
alter-text
Review và Khởi tạo API GAteway
  1. Sau khi khởi tạo xong API Gateway, thì ta quay về giao diện Lambda, ta sẽ thấy đã có API Gateway được trigger cho Lambda của mình.
alter-text
Giao diện AWS API Gateway

Tiếp theo ta sẽ tới phần cấu hình SSL cho API bằng ACM.

IV. Custom Domain & SSL

1. Tạo ACM

Tiếp theo, chúng ta cần cấu hình domain cho API Gateway vừa rồi, chúng sẽ tiến hình tạo custom domain và cấu hình SSL cho domain đó bằng AWS Certificate Manager.

Tạo Certificate

  1. Tìm kiếm và truy cập AWS Certificate Manager trên Console
  • Nhấn chọn Request a certificate
alter-text
Tại trang Route53
  1. Tại màn hình Request certificate:
  • Nhấn chọn request a public certificate
  • Nhấn Next
alter-text
Request certificate
  1. Tại màn hình Request public certificate:
  • Nhập domain name vào phần Fully qualified domain name
  • Tại mục Validation method, chọn DNS validation
alter-text
Khởi tạo Request Certificate.
  • Tại phần Key Algorithm, chọn RSA 2048
  • Nhấn Next để hoàn thiện
alter-text
Khởi tạo Request Certificate.
  1. Tại màn hình chi tiết của Certificate:
  • Nhấn chọn Create Records in Route 53
  • Sau khi vào màn hình create records thì nhấn Create Records để khởi tạo.
  • Tiếp theo bạn sẽ đợi một khoản thời gian để cho verify xanh lên là đã khởi tạo thành công.

alter-text
Khởi tạo Validate Record AWS Route 53
alter-text
Khởi tạo Validate Record AWS Route 53.
alter-text
Khởi tạo Validate Record AWS Route 53.

Tạo Custom Domain

  1. Tại màn hình API Gateway, ta chọn phần Custom Domain Names:
  • Nhấn chọn Create
alter-text
Custom domain names
  1. Tại màn hình Create domain name:
  • Điền tên domain vào phần domain name
  • Chọn API endpoint type: Regional
  • Tại mục ACM certificate, nhấn chọn ACM đã được thiết lập.
  • Nhấn Create Domain Name

alter-text
Tạo domain custom.
alter-text
Tạo domain custom.

  • Ở phần API Gateway Domain Name, đây sẽ là domain bạn sẽ cấu hình vào Route 53 bằng để có thể mapping domain của mình.
alter-text
Route53.
  1. Tại màn hình Custom domain names:
  • Chọn domain vừa tạo
  • Chọn tab API Mappings
  • Nhấn chọn Configure API Mappings
alter-text
Giao diện custom domain names.
  • Tiến hành chọn API Tại mục API
  • Chọn stage muốn mappings, ở đây mình sẽ chọn default
  • Nhấn Save
alter-text
Cấu hình API mappings.

Mappings Domain Name

  1. Tìm kiếm và truy cập AWS Route 53
  • Hosted Zones trên thanh điều hướng.
  • Nhấn chọn Hosted Zone của Domain của bạn.
alter-text
Cấu hình API mappings.
  1. Tại màn hình hosted zone của domain bạn:
  • Nhấn chọn Create Record
alter-text
Cấu hình domain name.
  1. Tại màn hình Create Record:
  • Nhập subdomain của bạn vào phần record name
  • Chọn Record Type là CNAME
  • Nhập API Gateway Domain Name vào phần Value
  • Nhấn Create Records
alter-text
Cấu hình domain name.

Vậy là xong, ta sẽ kiểm tra mọi thứ có hoạt động hay không bằng cURL.

alter-text
Kiểm tra API.

Có vẻ là đã hoàn thiện, vậy là đã xong các bước thiết lập.

V. Dọn dẹp tài nguyên

Chúng ta sẽ tiến hành các bước sau để xóa các tài nguyên chúng ta đã tạo trong bài thực hành này.

Xóa Lambda Function

  1. Truy cập giao diện quản trị dịch vụ Lambda
  • Click Functions.
  • Click chọn Functions của bạn.
  • Click Actions, chọn Delete.
  • Nhập delete vào pop-up và nhấn Delete.

alter-text
Dọn dẹp Lambda.
alter-text
Dọn dẹp Lambda.

  1. Truy cập giao diện quản trị dịch vụ ECR
  • Click Repositories.
  • Click chọn Delete.
  • Nhập delete vào pop-up và nhấn Delete.
alter-text
Dọn dẹp ECR.
  1. Truy cập giao diện quản trị dịch vụ API Gateway .
  • Click chọn Custom Domain Names.
  • Click chọn domain, nhấn tab API Mappings, chọn Configure API mappings.
  • Nhấn Remove các Mapping.
  • Click chọn APIs
  • Click chọn API của bạn.
  • Click chọn Delete.
  • Nhập confirm vào pop-up và nhấn Delete.

Như vậy là đã xong bài blog của chúng ta. Hẹn các bạn vào những bài viết khác của mình. Bái bai :3

Bài Viết Liên Quan

Ứng dụng AWS Rekognition cùng Fipix

Ứng dụng AWS Rekognition cùng Fipix

Xin chào tất cả các bạn, lại là mình đây. Ngày 26.07 vừa rồi mình rất may mắn khi được sếp của mình và các anh chị em ở Cloud Kinetics Việt Nam tạo điều kiện để tham gia, trình bày trong sự kiện Unlock Your Future with GenAI.

Đọc Thêm
[AWS] Chapter 0: AWS là gì?

[AWS] Chapter 0: AWS là gì?

  • Kai
  • June 24, 2024

Giới thiệu AWS (Amazon Web Services) là một nền tảng điện toán đám mây được phát triển và cung cấp bởi Amazon.

Đọc Thêm

[Docker] Chapter 1: Docker là gì?

  • Kai
  • January 24, 2021

Docker là một nền tảng mã nguồn mở dùng để phát triển, vận chuyển và chạy các ứng dụng. Docker cho phép bạn tách biệt ứng dụng của bạn khỏi cơ sở hạ tầng để bạn có thể triển khai phần mềm một cách nhanh chóng.

Đọc Thêm