Hệ thống có bốn service: user, order, payment, notification. Mỗi service tự validate JWT trong middleware riêng, cùng logic, cùng thư viện, nhưng mỗi team copy-paste một bản và chỉnh sửa theo cách khác nhau. Service user kiểm tra exp claim rồi mới check iss, service order làm ngược lại, service payment thêm bước introspection tới auth server mà hai service kia không có. Rate limit cũng tương tự: order dùng fixed window 100 req/min, payment dùng token bucket 50 req/min, user không có rate limit. CORS headers thì mỗi service trả một bộ khác nhau, frontend phải handle từng trường hợp.
Khi có bug trong logic validate JWT, ví dụ không check nbf (not before) claim, phải patch bốn service, bốn PR, bốn lần deploy. Một service quên patch, lỗ hổng vẫn tồn tại. Đây không phải vấn đề giả định, đây là thực tế của hầu hết hệ thống microservices khi cross-cutting concerns bị phân tán vào từng service thay vì tập trung tại một điểm.
API gateway giải quyết bài toán này bằng cách đặt một lớp trung gian giữa client và các service backend. Mọi request từ client đi qua gateway trước, gateway xử lý authentication, rate limiting, routing, request transformation, TLS termination, rồi mới forward request đã “sạch” tới service đích. Service chỉ cần lo business logic, không phải lo “request này có hợp lệ không” hay “client này có quyền gọi không”.
Gateway làm gì, và không nên làm gì
Hiểu nôm na thì API gateway giống như bảo vệ toà nhà, mọi người vào đều qua bảo vệ kiểm tra giấy tờ, bảo vệ chỉ đường vào đúng tầng, và không cần mỗi tầng tự có bộ quy trình kiểm tra riêng.
Trước khi đi sâu vào từng chức năng, cần vẽ rõ ranh giới. Gateway xử lý cross-cutting concerns, những thứ mà mọi request đều cần, bất kể đi tới service nào. Nếu một logic chỉ áp dụng cho một service cụ thể, nó thuộc về service đó, không phải gateway.
Request đi qua gateway trải qua một pipeline tuần tự: TLS termination (giải mã HTTPS, trả về HTTP thuần cho backend), authentication (validate token, reject nếu không hợp lệ), rate limiting (đếm và throttle nếu vượt quota), routing (match path/header tới đúng upstream service), và cuối cùng là forward request. Response chiều ngược lại có thể qua thêm bước transformation, thêm header, strip thông tin nội bộ, compress.
Routing, đưa request đến đúng service
Routing là chức năng cơ bản nhất của gateway: nhận request từ client, dựa vào URL path, HTTP method, header, hoặc query parameter để quyết định forward tới upstream service nào.
Path-based routing là pattern phổ biến nhất. /api/users/* đi tới user service, /api/orders/* đi tới order service. Cấu hình đơn giản, dễ hiểu, dễ debug. Nhược điểm là path phải tuân theo convention rõ ràng, nếu hai service cùng claim /api/products thì phải refactor path hoặc dùng thêm tiêu chí khác.
Header-based routing hữu ích cho versioning API hoặc canary deployment. Request có header X-API-Version: 2 route tới service v2, còn lại đi v1. Hoặc request có header X-Canary: true route tới instance canary đang chạy code mới. Pattern này mạnh nhưng khó debug hơn path-based vì header không hiển thị rõ trong access log mặc định, cần đảm bảo gateway log cả routing decision.
Canary routing mở rộng từ header-based: gateway split traffic theo tỷ lệ phần trăm. 5% request đi tới version mới, 95% đi version cũ. Kết hợp với metric chia theo version, đây là cách rollout an toàn mà không cần feature flag ở application layer. Kong, APISIX, Envoy đều hỗ trợ weighted upstream routing native.
Path rewriting cũng hay dùng: client gọi /api/v2/users/42 nhưng user service chỉ hiểu /users/42. Gateway strip prefix /api/v2 trước khi forward. Điều này cho phép thay đổi URL structure đối ngoại mà không ảnh hưởng code backend, rất hữu ích khi versioning API hoặc khi migrate service.
Authentication tại gateway
Đây là lý do phổ biến nhất để adopt gateway. Thay vì mỗi service tự validate JWT, gateway làm một lần cho tất cả.
JWT validation là flow đơn giản nhất: client gửi Authorization: Bearer <token>, gateway decode JWT, verify signature bằng public key (lấy từ JWKS endpoint của identity provider), kiểm tra exp, iss, aud claims. Nếu hợp lệ, gateway forward request kèm thêm header nội bộ chứa thông tin user đã decode, ví dụ X-User-ID: 42, X-User-Role: admin. Service backend đọc header này thay vì tự decode JWT, giảm coupling với auth logic.
Lưu ý bảo mật quan trọng: header nội bộ như X-User-ID phải được strip nếu client gửi lên, nếu không, client có thể tự set X-User-ID: 1 (admin) và bypass auth. Gateway phải luôn overwrite header nội bộ bằng giá trị từ JWT đã validate, không merge với header client gửi.
Token introspection dùng khi JWT không chứa đủ thông tin hoặc khi cần check token revocation real-time. Gateway gọi endpoint /introspect của auth server với access token, auth server trả về active: true/false kèm metadata. Đắt hơn JWT validation (thêm một network hop mỗi request) nhưng cho phép revoke token ngay lập tức, JWT thuần thì phải chờ token hết hạn.
Để giảm chi phí introspection, gateway thường cache kết quả với TTL ngắn (30-60 giây). Trade-off: token bị revoke sẽ vẫn valid trong khoảng TTL đó. Tuỳ use case mà chọn TTL phù hợp, ứng dụng banking có thể cần TTL 0 (introspect mọi request), ứng dụng content có thể chấp nhận TTL 5 phút.
API key management cho trường hợp client là service khác hoặc third-party integration. Gateway quản lý bộ API key, map key tới client identity và permission set. Khi request đến với header X-API-Key, gateway lookup key, xác định client, áp dụng rate limit và permission tương ứng. API key đơn giản hơn OAuth flow nhưng kém linh hoạt, thường dùng cho server-to-server communication hoặc public API có quota.
Rate limiting tại gateway
Rate limiting ở gateway có lợi thế lớn: tất cả request đi qua một điểm nên đếm chính xác, không bị phân tán giữa nhiều instance service. Ba chiến lược phổ biến, mỗi cái có trade-off khác nhau.
Fixed window chia thời gian thành các cửa sổ cố định, ví dụ mỗi phút. Đếm số request trong cửa sổ hiện tại, vượt threshold thì reject. Đơn giản nhất để implement, nhưng có vấn đề “burst at boundary”: nếu limit là 100 req/min, client có thể gửi 100 request ở giây cuối của phút này và 100 request ở giây đầu của phút sau, tổng cộng 200 request trong 2 giây, gấp đôi ý định thiết kế.
Sliding window giải quyết boundary burst bằng cách tính rate dựa trên cửa sổ trượt. Thay vì reset counter mỗi phút, tính số request trong 60 giây gần nhất tại thời điểm request đến. Chính xác hơn fixed window, nhưng tốn memory hơn vì phải lưu timestamp từng request (hoặc dùng approximation với weighted counter giữa hai window).
Token bucket linh hoạt nhất: mỗi client có “xô” chứa token, mỗi request tiêu một token, token được bổ sung đều đặn theo tốc độ cố định. Bucket có capacity tối đa, cho phép burst ngắn (dùng hết token trong bucket) nhưng sustained rate không vượt tốc độ bổ sung. Phù hợp cho API có traffic bursty nhưng cần cap sustained rate. Hầu hết gateway (Kong, APISIX, Envoy) implement token bucket hoặc variant của nó.
Khi gateway chạy nhiều instance (HA), rate limit counter phải chia sẻ giữa các instance, thường qua Redis hoặc in-memory store có replication. Nếu mỗi instance đếm riêng, client có thể gửi N × limit request (N là số instance) trước khi bị throttle. Redis-based counter là giải pháp phổ biến nhất, trade-off là thêm latency cho mỗi request (1 round-trip tới Redis, thường < 1ms trên cùng AZ).
Rate limit response nên trả header chuẩn để client biết còn bao nhiêu quota: X-RateLimit-Limit (tổng quota), X-RateLimit-Remaining (còn lại), X-RateLimit-Reset (khi nào reset). Khi bị throttle, trả 429 Too Many Requests kèm Retry-After header, client hiểu biết sẽ backoff thay vì retry liên tục.
TLS termination
Gateway nhận HTTPS từ client, giải mã TLS, forward HTTP thuần (hoặc mTLS) tới backend service. Lợi ích: backend không cần quản lý certificate, certificate renewal tập trung tại gateway, và traffic nội bộ giữa gateway-backend có thể chạy HTTP thuần nếu network đáng tin (VPC, service mesh). Nếu cần encryption end-to-end (compliance PCI-DSS, HIPAA), gateway re-encrypt bằng mTLS tới backend, tốn thêm CPU nhưng đáp ứng yêu cầu.
Certificate management tại gateway đơn giản hoá đáng kể so với mỗi service tự quản lý. Dùng cert-manager trên Kubernetes hoặc ACM trên AWS, certificate auto-renew tại gateway, backend service không cần biết cert là gì.
Request và response transformation
Gateway có thể thay đổi request trước khi forward và response trước khi trả client. Một số use case hợp lý: thêm correlation ID (X-Request-ID) vào mọi request nếu client không gửi, strip header nội bộ khỏi response (backend trả X-Internal-Debug nhưng client không nên thấy), thêm CORS headers đồng nhất cho mọi response.
Transformation phức tạp hơn, merge response từ nhiều service, reshape JSON, nên cẩn thận. Gateway mà bắt đầu parse body, transform schema, aggregate response từ nhiều upstream thì đang trượt dần vào lãnh thổ ESB (Enterprise Service Bus). Ranh giới hợp lý: gateway transform header và metadata, không transform body ngoại trừ trường hợp rất đơn giản.
Gateway pattern
Single gateway
Pattern đơn giản nhất: một gateway phục vụ mọi client, web, mobile, third-party API consumer. Mọi request đi qua cùng pipeline auth, rate limit, routing.
Ưu điểm là đơn giản: một config, một deployment, một nơi để monitor. Đủ dùng cho hầu hết hệ thống vừa và nhỏ. Nhược điểm lộ ra khi client khác nhau cần hành vi khác nhau: mobile app cần response gọn (ít field, ảnh nhỏ), web app cần response đầy đủ, third-party API cần format chuẩn hoá. Nếu dồn tất cả logic conditional này vào một gateway, config phình to và khó maintain.
BFF, Backend for Frontend
BFF pattern tạo một gateway riêng cho mỗi loại client. Web BFF xử lý request từ browser, trả HTML fragment hoặc JSON đầy đủ, handle cookie-based auth. Mobile BFF xử lý request từ app, trả JSON compact, handle bearer token, có thể aggregate data từ nhiều service vào một response để giảm số round-trip trên mạng mobile chậm.
BFF hợp lý khi client có yêu cầu khác biệt đáng kể, nhưng thêm complexity vận hành vì giờ phải deploy và monitor nhiều gateway. Mỗi BFF cũng có thể trở thành nơi tích tụ business logic “tiện thể”, team mobile thêm logic aggregate order history vào Mobile BFF, giờ BFF phải maintain business rule. Ranh giới cần rõ: BFF chỉ lo orchestration và adaptation, business logic thuộc về downstream service.
Ai own BFF cũng là câu hỏi tổ chức: team frontend hay team platform? Nếu frontend own, họ có thể iterate nhanh nhưng có thể thiếu expertise về reliability. Nếu platform own, frontend phải chờ platform team thêm endpoint. Mô hình phổ biến: frontend team own code BFF, platform team own infrastructure BFF (deployment, scaling, monitoring).
Sidecar gateway
Thay vì gateway tập trung, đặt proxy sidecar cạnh mỗi service instance. Envoy proxy là ví dụ điển hình, chạy trong cùng pod (Kubernetes) với service, xử lý mTLS, retry, circuit breaking, observability. Đây là nền tảng của service mesh (Istio, Linkerd).
Sidecar không thay thế gateway tập trung cho traffic north-south (client → backend). Nó giải quyết traffic east-west (service → service), cross-cutting concerns cho internal communication. Hệ thống lớn thường có cả hai: gateway cho north-south, sidecar mesh cho east-west.
Lựa chọn công cụ
Thị trường gateway rất đông đúc. Thay vì review từng tool, phân loại theo nhu cầu sẽ dễ chọn hơn.
Self-host, control nhiều, ops nhiều
Kong (dựa trên NGINX + Lua) là lựa chọn phổ biến nhất trong nhóm open-source. Ecosystem plugin phong phú, auth, rate limit, logging, transformation đều có plugin sẵn. Chạy với PostgreSQL hoặc Cassandra cho cluster mode, hoặc DB-less mode với declarative config (YAML/JSON). Kong Gateway (OSS) miễn phí, Kong Enterprise thêm RBAC, developer portal, analytics.
Apache APISIX (dựa trên NGINX + Lua, tương tự Kong) nhưng dùng etcd thay vì database, hot-reload config nhanh hơn. Performance benchmark thường ngang hoặc nhỉnh hơn Kong. Community Trung Quốc mạnh, đang phát triển nhanh.
Envoy là proxy L4/L7 từ Lyft, viết bằng C++, performance rất cao. Không phải gateway “out of the box” như Kong, cần thêm control plane (ví dụ Istio, Gloo Edge, Emissary-ingress) để có trải nghiệm gateway đầy đủ. Envoy là building block mạnh nhưng learning curve cao hơn.
Traefik tích hợp chặt với Docker và Kubernetes, auto-discover service qua label/annotation, cấu hình dynamic. Developer experience tốt cho team nhỏ đến trung bình. Plugin ecosystem nhỏ hơn Kong nhưng đủ cho hầu hết use case. Let’s Encrypt integration sẵn, certificate auto-renew không cần setup thêm.
NGINX (hoặc NGINX Plus) vẫn là reverse proxy phổ biến nhất. Cấu hình bằng file, stable, performance tốt. Nhưng thiếu nhiều tính năng gateway hiện đại (dynamic config reload, admin API, plugin ecosystem) so với Kong hay APISIX trừ khi dùng NGINX Plus (thương mại) hoặc viết Lua module.
Trade-off chung của self-host: team phải vận hành gateway, upgrade, patch security, scale, monitor. Đổi lại, có toàn quyền kiểm soát config, latency thấp (gateway cùng VPC với backend), và không phụ thuộc vendor pricing.
Managed, ít ops, ít control
AWS API Gateway có hai flavour: REST API (feature-rich, đắt hơn) và HTTP API (nhẹ hơn, rẻ hơn, ít feature). Tích hợp sâu với Lambda, IAM, Cognito. Pay-per-request pricing hấp dẫn cho traffic thấp-trung bình, nhưng ở high traffic (hàng triệu request/ngày) chi phí có thể cao hơn self-host (nhiều team chọn AWS API Gateway vì Lambda đã trong stack rồi, không phải vì so sánh kỹ với Kong, lý do hoàn toàn thực dụng). Latency overhead 10-30ms tuỳ config, chấp nhận được cho hầu hết use case nhưng không phù hợp nếu latency budget rất chặt.
GCP API Gateway và Apigee (cũng của Google) phục vụ hai phân khúc: API Gateway cho simple routing + auth, Apigee cho enterprise API management đầy đủ (developer portal, monetization, analytics). Cloud Endpoints là option khác nếu dùng gRPC.
Azure API Management (APIM) full-featured nhất trong ba cloud, policy engine mạnh, developer portal sẵn, transformation phức tạp. Nhưng pricing phức tạp và tier thấp có latency overhead đáng kể.
Managed gateway phù hợp khi team không muốn (hoặc không đủ người) vận hành infrastructure gateway. Trade-off: vendor lock-in (config format, plugin ecosystem riêng), latency overhead cao hơn self-host, và giới hạn customization.
Gateway là single point of failure
Mọi request đi qua gateway, nếu gateway chết, toàn bộ hệ thống không thể truy cập từ bên ngoài. Đây là rủi ro kiến trúc lớn nhất của gateway pattern và phải được thiết kế cho từ đầu.
High availability
Gateway phải chạy tối thiểu hai instance, lý tưởng là ba instance trở lên, phân tán cross-AZ. Load balancer phía trước (NLB trên AWS, hoặc DNS round-robin cho setup đơn giản) phân phối traffic giữa các instance. Health check từ load balancer tới gateway phải kiểm tra không chỉ “process đang chạy” mà còn “có thể route request”, health check endpoint nên thử route tới ít nhất một upstream để đảm bảo gateway thực sự functional.
Khi một instance gateway fail, load balancer phải detect nhanh (health check interval 5-10 giây, threshold 2-3 lần fail) và drain traffic. Nếu dùng Kubernetes, gateway chạy như Deployment với podAntiAffinity để đảm bảo pod không dồn vào cùng node, node chết thì chỉ mất một instance, không phải tất cả.
Graceful degradation
Khi upstream service chậm hoặc chết, gateway cần xử lý hợp lý thay vì cascade failure. Timeout cho mọi upstream call, nếu user service không trả lời trong 5 giây, gateway trả 504 thay vì giữ connection chờ vô hạn. Circuit breaker ngắt traffic tới upstream đang lỗi, khi error rate tới user service vượt 50% trong 30 giây, gateway ngừng forward request mới tới user service và trả 503 ngay, giảm load cho service đang stress. Sau thời gian cooldown, gateway thử gửi vài request probe, nếu service hồi, mở circuit trở lại.
Retry nên cấu hình cẩn thận ở gateway level. Retry request GET (idempotent) khi upstream trả 502/503 là hợp lý. Retry request POST (non-idempotent) có thể gây duplicate, chỉ retry nếu upstream chưa nhận request (connection refused, timeout trước khi gửi body). Retry với jitter (random delay) tránh thundering herd khi nhiều request cùng retry đồng thời.
Connection pooling và performance
Gateway maintain connection pool tới mỗi upstream service, thay vì mở TCP connection mới cho mỗi request (tốn thời gian TCP handshake + TLS handshake nếu có), tái sử dụng connection đã có. Connection pooling giảm latency đáng kể, đặc biệt khi upstream dùng HTTPS.
Cần tune pool size hợp lý: quá nhỏ thì request queue chờ connection, quá lớn thì tốn memory và file descriptor. Heuristic: pool size = expected concurrent requests tới upstream đó × 1.5. Monitor active connections và queue length, nếu queue thường xuyên > 0, pool đang quá nhỏ.
Latency overhead của gateway phụ biến, phụ thuộc vào số plugin active, logic transformation, và có gọi external service (Redis cho rate limit, auth server cho introspection) hay không. Gateway đơn giản (routing + header-based auth) thêm 1-5ms. Gateway phức tạp (introspection + Redis rate limit + body transformation) có thể thêm 10-30ms. Đo latency P99 của gateway riêng biệt và đặt budget, nếu vượt budget, review plugin chain.
Observability cho gateway
Gateway là điểm lý tưởng để thu thập telemetry vì mọi request đều đi qua.
Access log tại gateway capture mọi request: client IP, method, path, upstream service, response status, latency tổng, latency upstream. Structured log (JSON) với trace ID cho phép correlate với log của upstream service. Đây là nguồn truth đầu tiên khi debug “request không tới service” hay “response chậm”.
Metrics theo RED pattern (Rate, Errors, Duration) cho từng route và upstream. Dashboard gateway nên show: QPS tổng, QPS per route, error rate per upstream, latency P50/P95/P99 per route, rate limit rejection count, circuit breaker state. Khi gateway từ chối request (auth fail, rate limit, circuit open), metric phải phân biệt rejection reason, “bị reject vì rate limit” khác xa “bị reject vì auth fail” về hành động cần làm.
Distributed tracing bắt đầu tại gateway: tạo trace ID (nếu client không gửi traceparent), tạo span cho gateway processing, inject trace ID vào request forward tới upstream. Upstream tiếp nối trace. Khi debug latency, trace cho thấy rõ bao nhiêu thời gian nằm ở gateway (auth check, rate limit lookup) và bao nhiêu ở upstream.
Khi nào không cần gateway
Gateway không phải mặc định cho mọi hệ thống. Có trường hợp thêm gateway chỉ thêm complexity mà không giải quyết vấn đề thật.
Monolith đơn giản, một ứng dụng duy nhất xử lý mọi request. Auth, rate limit, routing đều trong cùng process. Thêm gateway phía trước chỉ thêm một hop network, thêm một thứ phải vận hành, mà không giải quyết vấn đề nào vì không có cross-service concern. Reverse proxy (NGINX) cho TLS termination và static file serving là đủ.
Service-to-service internal, khi service A gọi service B nội bộ trong cùng cluster, đi qua gateway tập trung không hợp lý. Traffic east-west (internal) nên đi trực tiếp hoặc qua service mesh (sidecar proxy), không qua north-south gateway. Gateway cho internal traffic tạo bottleneck không cần thiết và single point of failure cho mọi communication nội bộ.
Giai đoạn đầu startup, team 3-5 người, 2-3 service, traffic vài nghìn request/ngày. Auth middleware dùng chung qua shared library đủ dùng. Rate limit chưa cần vì traffic thấp. Thêm gateway lúc này là over-engineering, chi phí vận hành (learn, deploy, monitor, upgrade) cao hơn giá trị mang lại. Khi nào cần? Khi bắt đầu có service thứ 4-5 và cross-cutting logic duplicate trở thành pain point thật.
gRPC internal, nếu service communicate bằng gRPC nội bộ, gateway HTTP ở giữa phải translate HTTP↔gRPC, thêm complexity và latency. gRPC services nên gọi nhau trực tiếp hoặc qua gRPC-aware proxy (Envoy hỗ trợ gRPC native). Gateway cho gRPC chỉ cần khi expose gRPC service ra public client qua REST/JSON (gateway làm transcoding).
Anti-pattern
Business logic trong gateway
Gateway mà bắt đầu chứa logic “nếu user type là premium thì route tới service A, nếu free thì route tới service B, nếu trial hết hạn thì trả response HTML custom”, đó không còn là gateway, đó là application server ngụy trang. Business rule thay đổi thì phải deploy lại gateway, mà deploy gateway ảnh hưởng toàn bộ traffic, blast radius lớn hơn deploy một service.
Quy tắc: gateway quyết định đi đâu (routing) và có được đi không (auth, rate limit). Gateway không quyết định làm gì khi đến nơi. Nếu logic routing phụ thuộc vào business state (subscription tier, account status), logic đó nên ở service phía sau, service trả redirect hoặc appropriate response, gateway chỉ forward.
Gateway thành ESB
Enterprise Service Bus là pattern cũ: một bus trung tâm xử lý routing, transformation, orchestration, business rule, protocol mediation, tất cả dồn vào một component. ESB trở thành bottleneck vận hành: mọi thay đổi business logic cần deploy ESB, team ESB trở thành bottleneck tổ chức, performance giảm vì mỗi request qua quá nhiều xử lý.
API gateway chỉ cách ESB một bước trượt: thêm plugin transformation body, thêm plugin aggregate response, thêm plugin custom Lua script xử lý business logic, dần dần gateway phình to thành ESB. Giữ gateway thin: routing, auth, rate limit, header manipulation. Bất kỳ thứ gì phức tạp hơn nên ở application layer.
Config drift giữa environment
Gateway config staging khác production, route khác, rate limit threshold khác, plugin chain khác. Khi thay đổi config staging hoạt động tốt nhưng production break vì config không đồng nhất. Giải pháp: config gateway phải version control (Git), deploy qua CI/CD pipeline giống code, có diff review trước khi apply production. Kong DB-less mode, APISIX declarative config đều hỗ trợ pattern này.
Không test gateway config
Gateway config thay đổi ảnh hưởng mọi traffic, nhưng nhiều team không test config change trước khi apply. Ít nhất cần: syntax validation (config hợp lệ), smoke test (gateway khởi động được, route tới upstream hoạt động), và rollback plan (giữ config version trước, có thể revert trong giây). Kong và APISIX hỗ trợ config versioning; nếu tự build, script backup config trước khi apply.
Luồng request end-to-end qua API gateway
Để nối lại toàn bộ, hình dung một request tạo order đi qua hệ thống có gateway.
Vài điểm đáng chú ý trong flow này. Gateway xử lý TLS, auth, rate limit, order service nhận request đã “sạch” với X-User-ID header, không cần biết JWT là gì. Order service gọi payment service trực tiếp (east-west traffic), không qua gateway, đây là thiết kế đúng vì gateway chỉ cho north-south. Response chiều về, gateway strip header nội bộ và thêm CORS, client nhận response chuẩn.
Migration: từ không có gateway sang có gateway
Adopt gateway cho hệ thống đang chạy không phải big bang, cần migration dần dần.
Bước đầu tiên: deploy gateway song song, chỉ làm proxy pass-through, forward mọi request tới backend không thay đổi gì. Verify rằng gateway không break request nào, latency overhead chấp nhận được. Chạy song song 1-2 tuần, so sánh response giữa direct access và qua gateway.
Bước hai: chuyển TLS termination và CORS sang gateway. Đây là thay đổi nhỏ, ít rủi ro, nhưng giảm config duplicate ở backend ngay lập tức.
Bước ba: chuyển auth sang gateway. Giai đoạn này cần cẩn thận nhất vì auth sai là security incident. Chạy “shadow mode” trước: gateway validate token nhưng vẫn forward request (kể cả khi auth fail), log kết quả validation. So sánh kết quả gateway auth với backend auth, nếu 100% khớp trong một tuần, bật enforcement (gateway reject request auth fail). Giữ auth middleware ở backend thêm một thời gian như safety net, rồi remove khi đã confident gateway xử lý đúng.
Bước bốn: chuyển rate limiting sang gateway, retire logic rate limit rải rác ở backend.
Approach dần dần này giảm rủi ro đáng kể so với “deploy gateway + enable everything + cầu nguyện”. Mỗi bước có rollback rõ ràng: disable feature đó ở gateway, traffic đi thẳng tới backend như trước.
API gateway tập trung cross-cutting concerns vào một điểm, authentication, rate limiting, TLS, thay vì để từng service tự lo. Nguyên tắc vàng: giữ gateway thin; bất cứ thứ gì phức tạp hơn routing và auth là dấu hiệu gateway đang trở thành ESB. Adopt khi cross-cutting logic duplicate thành pain point thật, không phải từ ngày đầu startup.