Hướng dẫn gọi sự kiện hệ thống (system event) thông qua sự kiện nội bộ (internal event)
Back to graphqlBối cảnh
System event dùng để gọi một sự kiện ở hệ thống khác thông qua HTTP. Thay vì mỗi module tự biết danh sách endpoint đích và tự gửi request, hệ thống dùng một internal event trung gian có tên:
ezy_system_event
Trong code, tên này tương ứng với hằng:
INTERNAL_EVENT_NAME_EZY_SYSTEM_EVENT
Internal event này đóng vai trò như một “cổng chuyển tiếp”: module nghiệp vụ chỉ cần phát event nội bộ, còn plugin GraphQL admin sẽ nhận event đó và gửi HTTP POST tới các system endpoint đã cấu hình.
Kiến trúc tổng quát
sequenceDiagram
participant Business as Module nghiệp vụ
participant Internal as EventHandlerManager
participant Relay as GraphQL system event relay
participant Endpoint as System endpoint
participant Target as Event handler đích
Business->>Internal: handleEvent("ezy_system_event", payload)
Internal->>Relay: gọi handler của internal event
Relay->>Endpoint: POST payload + Bearer token
Endpoint->>Endpoint: kiểm tra eventName có được phép xử lý
Endpoint->>Target: handleEvent(eventName, data)
Target-->>Endpoint: result hoặc no content
Payload chuẩn
Khi muốn gọi một system event thông qua internal event, payload cần có dạng:
{
"eventName": "ten_system_event_can_goi",
"data": {
"field1": "value1",
"field2": "value2"
}
}
Trong đó:
-
eventName: tên system event thật sự muốn gọi ở hệ thống nhận. -
data: dữ liệu truyền cho event handler đích. - Internal event bên ngoài luôn là
ezy_system_event.
Ví dụ từ ecommerce, khi cần phát system event thông báo đơn hàng của user, module phát internal event như sau:
eventHandlerManager.handleEvent(
INTERNAL_EVENT_NAME_EZY_SYSTEM_EVENT,
mapBuilder()
.put("eventName", SYSTEM_EVENT_NAME_USER_ORDER_NOTIFICATION)
.put("data", mapBuilder()
.put("orderId", orderId)
.put("username", username)
.put("userDisplayName", userDisplayName)
.put("userEmail", userEmail)
.put("userPhoneNumber", userPhoneNumber)
.put("orderProducts", orderProducts)
.put("userRequestedDomain", userRequestedDomain)
.toMap()
)
.toMap()
);
Lưu ý: với ecommerce hiện tại, tên system event cụ thể đang là:
ezy_sytem_event_user_order_notification
Hãy dùng đúng chuỗi đang được khai báo trong hệ thống, kể cả khi tên có vẻ bị thiếu chữ.
Cách cấu hình bên gửi
Bên gửi cần có GraphQL admin plugin để làm relay cho internal event
ezy_system_event.Khi relay nhận được internal event, nó sẽ:
- Lấy danh sách system endpoint có loại
SYSTEM_ENDPOINT. - Chỉ lấy endpoint đang ở trạng thái
VISIBLE. - Bỏ qua endpoint không có token.
- Gửi HTTP POST tới từng endpoint.
- Thêm header:
Authorization: Bearer <token>
- Body request chính là payload của internal event.
Ví dụ body được gửi đi:
{
"eventName": "ezy_sytem_event_user_order_notification",
"data": {
"orderId": 1,
"username": "john",
"userDisplayName": "John",
"userEmail": "john@example.com",
"userPhoneNumber": "0900000000",
"orderProducts": [
{
"productCode": "P001",
"quantity": 1,
"price": 100000
}
],
"userRequestedDomain": "example.com"
}
}
Cách cấu hình bên nhận
Bên nhận cần expose API nhận system event, hiện tại là:
POST /api/v1/system-event
API này nhận body:
{
"eventName": "ten_system_event",
"data": {}
}
Trước khi gọi event handler thật, hệ thống kiểm tra
eventName có nằm trong danh sách system event được phép xử lý hay không.Danh sách này được cấu hình bằng setting:
allowing_handling_system_event_names
Nếu
eventName không nằm trong danh sách cho phép, request sẽ bị từ chối với lỗi forbidden.Ví dụ với ecommerce
Luồng thông báo đơn hàng trong ecommerce hoạt động như sau:
- Khi có dữ liệu thông báo đơn hàng, ecommerce phát internal event:
user_order_notification_append
- Một handler trong ecommerce nhận event này.
- Nếu setting cho phép gửi system event đơn hàng đang bật, handler tiếp tục phát internal event:
ezy_system_event
- Payload bên trong có
eventNamelà system event thông báo đơn hàng. - GraphQL relay nhận
ezy_system_eventvà gửi POST tới các system endpoint đã cấu hình. - Hệ thống nhận kiểm tra whitelist rồi gọi handler tương ứng với system event đích.
Điều kiện để event chạy thành công
Để gọi system event qua internal event thành công, cần đủ các điều kiện sau:
- Bên gửi có handler cho internal event
ezy_system_event. - Có ít nhất một system endpoint đang
VISIBLE. - System endpoint có bearer token hợp lệ.
- Bên nhận cho phép xử lý
eventNametrong settingallowing_handling_system_event_names. - Bên nhận có event handler tương ứng với
eventName. - Payload
datađúng schema mà event handler đích mong đợi.
Điểm cần lưu ý
Internal event
ezy_system_event không phải là event nghiệp vụ cuối cùng. Nó chỉ là event trung gian để chuyển payload sang system endpoint.GraphQL relay không tự validate chi tiết schema của
data khi chuyển tiếp. Việc dữ liệu có hợp lệ hay không phụ thuộc vào event handler đích.Nếu một endpoint lỗi khi gọi HTTP, relay ghi log cảnh báo và tiếp tục xử lý các endpoint khác.
Kết luận
Để gọi system event thông qua internal event, module nghiệp vụ chỉ cần phát internal event
ezy_system_event với payload gồm eventName và data. GraphQL admin plugin sẽ đảm nhiệm phần chuyển tiếp HTTP tới các system endpoint đã cấu hình, còn hệ thống nhận sẽ whitelist eventName trước khi gọi event handler thật.