ADR-0002: Giao tiếp Go ↔ NestJS thuần qua Kafka, không bao giờ gọi HTTP
- Status: Accepted
- Date: ~2026-06-27 (backfilled 2026-07-25)
- Supersedes: —
- Superseded by: —
Bối cảnh
Với Go service chạy song song NestJS (ADR-0001), cần quyết định kênh giao tiếp. Nếu cho phép Go gọi HTTP trực tiếp vào NestJS (hoặc ngược lại), 2 hệ thống sẽ coupling chặt về availability/latency của nhau — đúng vấn đề mà việc tách Go ra vốn muốn tránh (VNPay IPN cần <50ms, không thể phụ thuộc NestJS đang bận).
Quyết định
Nguyên tắc bất biến: Go service không bao giờ gọi HTTP endpoint của
NestJS. Toàn bộ giao tiếp Go ↔ NestJS đi qua Kafka produce/consume.
Ngoại lệ duy nhất: availability-engine được đọc trực tiếp PostgreSQL
(booking_db, read-only) để check overlap slot — không qua NestJS API.
Lựa chọn khác đã cân nhắc
- HTTP call trực tiếp khi cần dữ liệu tức thời (vd: analytics-pipeline gọi field-service lấy thêm context): tiện hơn khi cần dữ liệu không có sẵn trong event payload, nhưng tạo coupling đồng bộ giữa 2 hệ thống vốn được tách ra để độc lập về availability — loại; giải pháp đúng là làm event payload đủ giàu thông tin thay vì gọi ngược.
- gRPC giữa Go và NestJS: giảm overhead so với REST, nhưng vẫn là giao tiếp đồng bộ, không giải quyết vấn đề coupling — loại vì lý do tương tự.
Hệ quả
- Được: Go service hoàn toàn độc lập về uptime với NestJS — nếu NestJS down, Go vẫn tiếp tục consume/produce Kafka bình thường (trừ dữ liệu cần aggregate về sau); dễ reason về failure mode (chỉ cần theo dõi Kafka broker + Go service, không phải toàn bộ chuỗi HTTP).
- Đánh đổi: mọi dữ liệu Go cần phải có sẵn trong Kafka event payload hoặc
trong
booking_db(chỉ availability-engine) — nếu thiếu field, phải sửa NestJS để emit thêm, không thể "tiện tay" gọi API lấy bù; độ trễ dữ liệu eventual-consistent thay vì real-time.
Liên kết
- Docs liên quan:
README.md(mục "Nguyên tắc bất biến"),pkg/events/ - ADR liên quan: ADR-0001