1. API Gateway là gì?
API Gateway thực chất là reverse proxy được cải tiến, cung cấp nhiều tùy chỉnh và linh hoạt hơn so với reverse proxy thông thường. API Gateway hoạt động như một "giao diện" của API nằm giữa Client và các dịch vụ API (Catalog/Ordering Service).
API Gateway chịu trách nhiệm điều phối các yêu cầu API, áp dụng các chính sách về lưu lượng (throttling, caching), các chính sách bảo mật (authorization, authentication), thu thập dữ liệu về lưu lượng truy cập, điều phối các công cụ chuyển đổi để chỉnh sửa yêu cầu/phản hồi ngay lập tức.
2. Chức năng của API Gateway
2.1 API Security (Bảo mật cho API)
Khi public API ra bên ngoài, bạn chắc chắn phải bảo vệ nó khỏi nhưng truy cập trái phép hay nói cách khác chỉ các client có đủ quyền mới có thể tương tác với các dịch vụ tương ứng, sau đây là một số các kĩ thuật phổ biến để bảo mật API.
2.2.1 API Key
API Key là một chuỗi ký tự duy nhất được cấp phát cho mỗi client sử dụng API. Key này sẽ được truyền cùng với yêu cầu HTTP để xác thực (authentication) danh tính của client trước khi truy cập dịch vụ.
# Kong Gateway Demo
# đăng kí consumer
curl -X POST http://localhost:8001/consumers/ --data "username=partner_001"
# kiểm tra đăng kí
curl -X GET http://localhost:8001/consumers/
# đăng kí API cần được bảo vệ
curl -X POST http://localhost:8001/apis/movies/plugins \
--data "name=key-auth" \
--data "config.key_names=apikey
# tạo key
curl -X POST http://localhost:8001/consumers/3f3d9926-349c-4bb2-b378-9b6a6f40a1cb/key-auth -d
API Key tương tự như chìa khoá để vào nhà, nên miễn client nào có khoá là gọi được API của chúng ta, để bảo vệ người dùng nếu chẳng may lộ Key ra ngoài mà không biết, một số nền tảng đặt ra thời hạn sử dụng cho Key của họ, ví dụ như Facebook là 3 tháng. Vì thời gian tồn tại khá dài nên API Key thường phục vụ cho nhu cầu xác thực server-to-server, quản lý nội bộ, cung cấp quyền truy cập cho các đối tác.
2.1.2 OAuth2
OAuth2 là một tiêu chuẩn được sử dụng rộng rãi để cấp quyền truy cập (authorization) cho các ứng dụng bên thứ ba vào các tài nguyên của người dùng mà không cần tiết lộ thông tin đăng nhập của họ.
Thông thường các access_token
được tạo ra từ quá trình uỷ quyền OAuth2 sẽ có thời gian tồn tại ngắn, ví dụ khi bạn login tài khoản Facebook ở máy lạ, Facebook sẽ không cấp phát 1 access_token
có thời gian tồn tại dài vì lo ngại vấn đề bảo mật.
# Cấp phát token cho một bên thứ 3 truy xuất vào scope read_profile, read_history
curl -X POST http://localhost:8001/apis/movies/plugins \
--data "name=oauth2" \
--data "config.enable_authorization_code=true" \
--data "config.token_expiration=240" \
--data "config.scopes=read_profile,read_history"
2.1.3 JWT Token
JWT là phương pháp xác thực được sử dụng phổ biến nhất hiện nay, JWT là một chuỗi ký tự mã hóa được tạo ra để đại diện cho một tập hợp các thông tin (claims). Nó thường bao gồm ba phần: Header (chứa thông tin về thuật toán mã hóa), Payload (chứa dữ liệu cần truyền tải như thông tin người dùng hoặc quyền truy cập), và Signature (chữ ký mã hóa đảm bảo tính toàn vẹn của token).
# Bật JWT Plugin
curl -X POST http://localhost:8001/apis/movies/plugins \
--data "name=jwt" \
--data "config.claims_to_verify=exp
# Cấp phát JWT Token
import jwt
import datetime
def create_jwt_token(user_id):
payload = {
"user_id": user_id,
"exp": datetime.datetime.utcnow() + datetime.timedelta(hours=2) # Token có thời hạn 2 giờ
}
token = jwt.encode(payload, "your-secret-key", algorithm="HS256")
return token
2.2 Rate limiting (Giới hạn tần suất)
Có một số vấn đề về tần suất gọi API từ phía Client mà bạn cần phải đối mặt khi thiết lập API Gateway:
- Rất nhiều yêu cầu xuất phát từ một người dùng trong một giây (crawler), khiến API Gateway quá tải và không thể xử lý các yêu cầu khác.
- Đảm bảo sự công bằng trong việc xử lý các yêu cầu có mức độ ưu tiên thấp/cao trong hệ thống. (ưu tiên Cao: thanh toán vé xem phim, ưu tiên Thấp: tải lại trang Profile user)
Giới hạn tần suất (Rate limiting) trên API Gateway giúp giải quyết các tình huống trên.
- Giới hạn số lượng request mà 1 client có thể gửi: Để bảo vệ API Gateway khỏi tình trạng bottleneck, chúng ta nên ngăn chặn việc một client gửi quá nhiều request. Bạn có thể đặt số lượng request được phép dựa trên một khoảng thời gian cụ thể (60 request/giây).
- Thiết lập giới hạn cao hơn cho các yêu cầu có mức độ ưu tiên cao: Ví dụ 500 yêu cầu/phút, nếu số lượng yêu cầu thanh toán vé vượt quá 500/phút, API Gateway sẽ từ chối các yêu cầu tiếp theo hoặc trả về lỗi 429 (Too Many Requests).
# Kong Gateway Demo
services:
- name: booking-transactions
url: http://booking.200lab.io
plugins:
- name: rate-limiting
config:
minute: 500
policy: local
services:
- name: informational-queries
url: http://user.200lab.io
plugins:
- name: rate-limiting
config:
minute: 100
policy: local
2.3 Caching (Lưu trữ tạm thời)
Caching là quá trình lưu trữ tạm thời các phản hồi từ các yêu cầu API để tăng tốc độ truy cập và giảm tải cho máy chủ backend. Khi một yêu cầu được gửi đến API Gateway, thay vì luôn phải gửi yêu cầu đó đến máy chủ backend, API Gateway có thể lấy dữ liệu từ bộ nhớ đệm (cache) nếu dữ liệu đó đã được lưu trữ từ trước và vẫn còn hiệu lực. Điều này giúp giảm thời gian phản hồi và tiết kiệm tài nguyên.
curl -i -X POST http://localhost:8001/apis/movies/plugins \
--data "name=proxy-cache" \
--data "config.strategy=memory" \
--data "config.content_type=text/html,application/json" \
--data "config.cache_ttl=300" \
--data "config.memory=dict" \
--data "config.cache_control=true"
2.4 Load Balancing (Cân bằng tải)
Load balancing là quá trình phân phối các yêu cầu từ người dùng đến nhiều máy chủ backend khác nhau để đảm bảo rằng không có máy chủ nào bị quá tải. Điều này giúp tăng cường hiệu suất, độ tin cậy và khả năng mở rộng của hệ thống, đảm bảo rằng các dịch vụ luôn sẵn sàng phục vụ người dùng. Các thuật toán cân bằng tải phổ biến là: round-robin, least-connections, IP-hash.
# Tạo upstreams
curl -i -X POST http://localhost:8001/upstreams/ --data "name=users.service"
# Add các targets vào upstreams
curl -i -X POST http://localhost:8001/upstreams/users.service/targets \
--data "target=localhost:5000"
curl -i -X POST http://localhost:8001/upstreams/users.service/targets \
--data "target=localhost:5001"
curl -X PATCH http://localhost:8001/apis/users \
--data 'upstream_url=http://users.service
2.5 Protocol Translation (Chuyển đổi Giao thức)
Protocol Translation là quá trình chuyển đổi dữ liệu từ một giao thức (protocol) này sang một giao thức khác. Cho phép hệ thống hiện tại giao tiếp với các hệ thống cũ dù cả hai sử dụng giao thức khác nhau.
# Chuyển đổi từ HTTP/REST sang gRPC
curl -i -X POST http://localhost:8001/services/ \
--data "name=ride-service" \
--data "protocol=grpc" \
--data "host=ride-service-backend" \
--data "port=50051"
# Chuyển đổi từ HTTP/REST sang SOAP:
curl -i -X POST http://localhost:8001/services/ \
--data "name=payment-service" \
--data "protocol=http" \
--data "host=payment-service-backend" \
--data "path=/payment"
2.6 Routing (Định tuyến)
API Gateway chịu trách nhiệm định tuyến các yêu cầu đến đúng dịch vụ backend dựa trên các tiêu chí như đường dẫn URL, phương thức HTTP, HTTP Header hoặc thông số truy vấn. Ví dụ: điều hướng yêu cầu đến /api/v1/users
tới dịch vụ quản lý người dùng, trong khi yêu cầu đến /api/v1/orders
sẽ được định tuyến tới dịch vụ quản lý đơn hàng.
curl -i -X POST http://localhost:8001/services/ \
--data "name=users-service" \
--data "url=http://users-service-backend:8000"
curl -i -X POST http://localhost:8001/services/ \
--data "name=orders-service" \
--data "url=http://orders-service-backend:8000"
curl -i -X POST http://localhost:8001/services/users-service/routes \
--data "paths[]=/api/v1/users"
curl -i -X POST http://localhost:8001/services/orders-service/routes \
--data "paths[]=/api/v1/orders"
2.7 Service Discovery (Khám phá dịch vụ)
API Gateway có thể tự động phát hiện các dịch vụ backend mới hoặc thay đổi thông qua các hệ thống như DNS, Consul, hoặc Kubernetes. Ví dụ: tự động phát hiện và định tuyến đến các instances mới của một microservice khi chúng được triển khai.
curl -i -X POST http://localhost:8001/upstreams/ \
--data "name=users-upstream" \
--data "service_discovery.type=consul" \
--data "service_discovery.name=users-service"
curl -i -X POST http://localhost:8001/services/ \
--data "name=users-service" \
--data "host=users-upstream"
curl -i -X POST http://localhost:8001/services/users-service/routes \
--data "paths[]=/api/v1/users"
2.8 Logging and Monitoring (Ghi nhật ký và giám sát)
API Gateway có thể ghi lại các yêu cầu và phản hồi, đồng thời cung cấp thông tin giám sát như: số lượng yêu cầu, thời gian phản hồi, và tỷ lệ lỗi.
curl -i -X POST http://localhost:8001/services/{service}/plugins \
--data "name=http-log" \
--data "config.http_endpoint=http://your-log-server:1234" \
--data "config.method=POST"
3. Kết luận
API Gateway là một thành phần quan trọng và không thể thiếu trong kiến trúc microservices. Nó không chỉ đóng vai trò là điểm trung gian giữa các client và backend services mà còn cung cấp một loạt các chức năng mạnh mẽ như routing, load balancing, security, caching, protocol translation, service discovery, và logging & monitoring.
Những chức năng này giúp API Gateway quản lý lưu lượng truy cập, bảo mật các dịch vụ backend, tối ưu hóa hiệu suất, đảm bảo rằng hệ thống của bạn luôn sẵn sàng và hoạt động hiệu quả.
Các bài viết liên quan tại Blog 200Lab:
Bài viết liên quan
Giới thiệu Kiến trúc Backend for Frontend (BFF)
Nov 16, 2024 • 10 min read
Flask là gì? Hướng dẫn tạo Ứng dụng Web với Flask
Nov 15, 2024 • 7 min read
Webhook là gì? So sánh Webhook và API
Nov 15, 2024 • 8 min read
Spring Boot là gì? Hướng dẫn Khởi tạo Project Spring Boot với Docker
Nov 14, 2024 • 6 min read
Two-Factor Authentication (2FA) là gì? Vì sao chỉ Mật khẩu thôi là chưa đủ?
Nov 13, 2024 • 7 min read
Test-Driven Development (TDD) là gì? Hướng dẫn thực hành TDD
Nov 13, 2024 • 6 min read