FaunaDB Eventhooks: filtering alert conditions without duplicate notifications
0 reputation · 14 Apr 2022, 17:41 UTC
0 reputation · 14 Apr 2022, 17:41 UTC
I want to use FaunaDB Eventhooks to push alerts to an external endpoint only when a document change meets specific criteria, so routine writes do not trigger notification noise. The filtering logic would live inside the Eventhook function itself.
Because Eventhooks execute within the transaction, a failed or slow external call can roll back the write or push the transaction toward its time limit. That makes me hesitant to put a real notification service directly in the hook path. I am also unsure how retries behave: if the endpoint times out but actually received the call, a retried transaction could emit the same alert twice unless I build idempotency into the receiving side.
I can gate the external call behind a conditional check on the changed document, but I have not found clear guidance on whether the hook should return success silently when criteria are unmet, or whether there is a cleaner suppression mechanism.
35275 reputation · 15 Apr 2022, 01:59 UTC
1. Conditional logic inside the Eventhook function is the intended suppression mechanism. FaunaDB does not provide a declarative filter at the hook configuration level. You write an FQL function that inspects the event payload (the changed document, operation type, etc.) and returns null or an empty result when criteria are not met. This silently suppresses the external call without affecting the originating transaction.
2. The external call does not consume the source transaction's time budget. Eventhooks are asynchronous: they fire after the triggering transaction commits. A slow or failing HTTP call cannot roll back the write or push the original transaction toward its timeout. The hook itself has its own execution ceiling (typically a few seconds), but it is decoupled from the writer's latency.
3. Receiver-side idempotency is the only reliable safeguard against duplicates. FaunaDB guarantees at-least-once delivery. Network retries, internal restarts, or transient endpoint failures can cause the same event to be delivered multiple times. The standard pattern is to include a stable identifier—such as the transaction ID (event.transaction) or the document's version timestamp—in the payload, and have the receiver deduplicate on that key.
CreateFunction({
name: "alert_on_status_change",
body: Query(Lambda(["event"],
Let({
doc: Select(["data", "document"], Var("event")),
prev: Select(["data", "prev"], Var("event")),
shouldAlert: Not(Equals(Select(["data", "status"], Var("doc")),
Select(["data", "status"], Var("prev"))))
},
If(Var("shouldAlert"),
Do(
Call("http_post", {
url: "https://alerts.example.com/ingest",
headers: { "Content-Type": "application/json" },
body: {
txnId: Select(["transaction"], Var("event")),
docRef: Select(["ref"], Var("doc")),
newStatus: Select(["data", "status"], Var("doc"))
}
}),
null
),
null
)
))
}))The If branch returns null when the condition fails, which tells FaunaDB "nothing to deliver" for this event. No HTTP request is made.
status; confirm no request reaches your endpoint (check logs or a request bin).status; confirm a single POST arrives with the expected txnId.What is the expected peak write throughput on the collection? If it exceeds a few hundred events per second, you may need to batch or queue deliveries outside the hook to avoid overwhelming the endpoint or hitting FaunaDB's concurrent hook execution limits.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.