After reading source code of the watch command implementation, I found the way to do it in HTTP API. Note that this is undocumented, use it at your own risk.
Suppose to monitor the changes of KV under the path of /xxx
.
First emit the following request.
GET http://your-consul.com:8500/v1/kv/xxx?recurse=true&stale=true
Consul would response this request immediately.
Connection: keep-alive
Content-Length: 209
Content-Type: application/json
Date: Sun, 13 Nov 2022 00:27:04 GMT
Vary: Accept-Encoding
Via: 1.1 proxy-server (squid/5.5)
X-Cache: MISS from proxy-server
X-Cache-Lookup: MISS from proxy-server:3128
X-Consul-Default-Acl-Policy: allow
X-Consul-Index: 3386097
X-Consul-Knownleader: true
X-Consul-Lastcontact: 0
X-Consul-Query-Backend: blocking-query
The X-Consul-Index
http header is what we are looking for.
Then emits another request with the index.
GET http://your-consul.com:8500/v1/kv/xxx?index=3386097&recurse=true&stale=true
Now this request will stuck till a change occurs.
When this request is responsed, the payload contains the details of all children KV at given path. X-Consul-Index
will also be included in response HTTP header, you need update the index
query string if you want to watch again.
So generally, you can watch changes via HTTP API as what the consul tool does. Note that you need implement the logic carefully, to handle timeout / network error / etc.