go
cr, err := client.Watch.Watch(context.Background(), &v1.WatchRequest{
TenantId: "t1",
SnapToken: "",
})
// handle stream response
for {
res, err := cr.Recv()
if err == io.EOF {
break
}
// res.Changes
}
const permify = require("@permify/permify-node");
const {WatchResponse} = require("@permify/permify-node/dist/src/grpc/generated/base/v1/service");
function main() {
const client = new permify.grpc.newClient({
endpoint: "localhost:3478",
});
let res = client.watch.watch({
tenantId: "t1",
snapToken: ""
});
handle(res);
}
async function handle(res: AsyncIterable<WatchResponse>) {
for await (const response of res) {
// response.changes
}
}
{
"result": {
"changes": {
"snap_token": "<string>",
"data_changes": [
{
"operation": "OPERATION_UNSPECIFIED",
"tuple": {
"entity": {
"type": "<string>",
"id": "<string>"
},
"relation": "<string>",
"subject": {
"type": "<string>",
"id": "<string>",
"relation": "<string>"
}
},
"attribute": {
"entity": {
"type": "<string>",
"id": "<string>"
},
"attribute": "<string>",
"value": {
"@type": "<string>"
}
}
}
]
}
},
"error": {
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}
}{
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}Watch Service
Watch API
POST
/
v1
/
tenants
/
{tenant_id}
/
watch
go
cr, err := client.Watch.Watch(context.Background(), &v1.WatchRequest{
TenantId: "t1",
SnapToken: "",
})
// handle stream response
for {
res, err := cr.Recv()
if err == io.EOF {
break
}
// res.Changes
}
const permify = require("@permify/permify-node");
const {WatchResponse} = require("@permify/permify-node/dist/src/grpc/generated/base/v1/service");
function main() {
const client = new permify.grpc.newClient({
endpoint: "localhost:3478",
});
let res = client.watch.watch({
tenantId: "t1",
snapToken: ""
});
handle(res);
}
async function handle(res: AsyncIterable<WatchResponse>) {
for await (const response of res) {
// response.changes
}
}
{
"result": {
"changes": {
"snap_token": "<string>",
"data_changes": [
{
"operation": "OPERATION_UNSPECIFIED",
"tuple": {
"entity": {
"type": "<string>",
"id": "<string>"
},
"relation": "<string>",
"subject": {
"type": "<string>",
"id": "<string>",
"relation": "<string>"
}
},
"attribute": {
"entity": {
"type": "<string>",
"id": "<string>"
},
"attribute": "<string>",
"value": {
"@type": "<string>"
}
}
}
]
}
},
"error": {
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}
}{
"code": 123,
"message": "<string>",
"details": [
{
"@type": "<string>"
}
]
}The Permify Watch API acts as a real-time broadcaster that shows changes in the relation tuples.
The Watch API exclusively supports gRPC and works with PostgreSQL, given the track_commit_timestamp option is enabled. Please note, it doesn’t support in-memory databases or HTTP communication.
For performance guidance, scaling strategies, and reconnection best practices, see Watch — Operations.
Requirements
- PostgreSQL database set up with track_commit_timestamp option enabled
Enabling track_commit_timestamp on PostgreSQL
To ensure data consistency and synchronization between your application and Permify, enable track_commit_timestamp on your PostgreSQL server. This can be done by executing the following options in your PostgreSQL:Option 1: SQL Command
- Open your PostgreSQL command line interface.
-
Execute the following command:
ALTER SYSTEM SET track_commit_timestamp = ON; -
Reload the configuration with the following command:
SELECT pg_reload_conf();
Option 2: Editing postgresql.conf
-
Find and open the postgresql.conf file in a text editor. Its location depends on your PostgreSQL installation. Common
locations are:
- Debian-based systems: /etc/postgresql/[version]/main/postgresql.conf
- Red Hat-based systems: /var/lib/pgsql/data/postgresql.conf
-
Add or modify the following line in the postgresql.conf file:
track_commit_timestamp = on - Save and close the postgresql.conf file.
-
Reload the PostgreSQL configuration for the changes to take effect. This can be done via the PostgreSQL console:
Or if you have command line access, use:
SELECT pg_reload_conf();sudo service postgresql reload
Important Configuration Requirement: To use the Watch API, it must be enabled in your configuration file. Add or modify the following lines:
service:
watch:
enabled: true
Path Parameters
Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \“[a-zA-Z0-9-,]+\“, max 64 bytes.
Body
application/json
WatchRequest is the request message for the Watch RPC. It contains the details needed to establish a watch stream.
The snap token to avoid stale cache, see more details on Snap Tokens.