Watching Relationship Changes
The Watch API (opens in a new tab) in SpiceDB enables clients to monitor changes made to Relationships within the system.
Watch events are generated when relationships are created, touched, or deleted through the WriteRelationships (opens in a new tab), DeleteRelationships (opens in a new tab), or the bulk import API.
Subscribing to Watch
To subscribe to receive watch changes, the Watch
API call is made:
watcher = client.Watch(WatchRequest{})
for resp in watcher:
... process the update ...
This will start returning all updates to relationships from the time at which the API call was made.
Receiving historical updates
Historical updates (i.e. relationship changes in the past) can be retrieved by specifying a ZedToken in the WatchRequest
:
watcher = client.Watch(WatchRequest{
OptionalStartCursor: myZedToken
})
Historical changes can only be requested until the configured garbage collection window on the underlying datastore. This is typically 24 hours, but may differ based on the datastore used.
Ensuring continuous processing
To ensure continuous processing, the calling client should execute the Watch
call in a loop, sending in the last received ZedToken from ChangesThrough
if the call disconnects:
while not_canceled:
last_zed_token = None
try:
watcher = client.Watch(WatchRequest{
OptionalStartCursor: last_zed_token
})
for resp in watcher:
... process the update ...
last_zed_token = resp.ChangesThrough
except Exception:
... log exception ...
continue
Transaction Metadata
SpiceDB's WriteRelationships (opens in a new tab) and DeleteRelationships (opens in a new tab) APIs support an optional metadata block called the Transaction Metadata (opens in a new tab).
When optional_transaction_metadata
is specified on the WriteRelationships (opens in a new tab) or DeleteRelationships (opens in a new tab) request, it will be stored and returned alongside the relationships in the Watch API:
client.WriteRelationships(WriteRelationshipsRequest{
Updates: [
{ Relationship: "document:somedoc#viewer@user:tom" }
],
OptionalTransactionMetadata: {
"request_id": "12345"
}
})
...
WatchResponse{
Updates: [
{ Relationship: "document:somedoc#viewer@user:tom" }
],
OptionalTransactionMetadata: {
"request_id": "12345"
}
}
This allows callers to correlate write operations and the updates that come from the Watch API.