GraphQL
Quick Reference
The best way to explore the GQL API is through GraphiQL. See how to setup GraphiQL in the turorial.
To learn more about GraphQL itself, read the docs.
Setup
Configure the STATETRACE_GQL_API_KEY
environment variable of your state instance with a key at least 32 characters long. Set the STATETRACE_PORT
environment variable to what you want the HTTP server to bind to:
statetrace:
image: statetraceofficial/statetrace-beta
environment:
- STATETRACE_GQL_API_KEY=12345678901234567890123456789012
- PORT=4000
The GraphQL endpoint will run located at /graphql/api/v1/
of your running statetrace instance.
Now you can make a GQL query:
curl -g \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 12345678901234567890123456789012" \
-d '{"query":"query{scan(inboundName: \"Postgres DB\") { rowLsnId }}"}' \
http://localhost:4000/graphql/api/v1/
Query Reference
Below is a list of all available queries
StreamRow Refrence
Scan and Search results come in as a StreamRow, below find all available fields to query:
Scanning the Buffer's Stream
Scanning the stream of changes from the buffer is easy. The scan starts from the earliest changes to the most recent changes at the end.
rowLsnId
(LSN = Log Sequence Number) uniquely identifies a row change within an inbound and is monotonically incrementing logical timestamp. This means that all changes are ordered based on rowLsnId
.
Get beginning of buffer
To grab the beginning of the buffer run scan
query{
scan(inboundName: "Postgres DB") {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Results in:
{
"data": {
"scan": [
{
"relationName": "django_migrations",
"relationSchema": "public",
"rowLsnId": "0x0DC97A33405711ECA69C0242AC1A0004000000000000000500000004",
"rowPk": [
"1"
],
"rowRecord": {
...
}
},
],
...
}
}
Get the next slice of buffer
To grab the next group of events from the buffer use the fromLsn
argument with the last rowLsnId
of the previous chunk.
query{
scan(inboundName: "Postgres DB", fromLsn: "0x0DC97A33405711ECA69C0242AC1A000400000000000000050000007C") {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Limit buffer slice by size
Limit the number of results returned by the scan.
query{
scan(inboundName: "Postgres DB", limit: 3) {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Limit buffer slice by Lsn
Use limitLsn
to contrain the maximum ID that is returned.
query{
scan(
inboundName: "Postgres DB",
fromLsn: "0x0DC97A33405711ECA69C0242AC1A000400000000000000050000007C",
limitLsn: "0x0DC97A33405711ECA69C0242AC1A000400000000000000050000007E"
) {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
This allows you to scan the buffer completely.
Get a single change
If you already know the LSN of the change you wish to query you can access it directly.
getChange
query{
getChange(
inboundName: "Postgres DB",
lsn: "0x0DC97A33405711ECA69C0242AC1A000400000000000000050000007C"
) {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Collector States
Sometimes you need to know whether or not an inbound collector is online. You can do this by querying the latest statuses of inbound and outbounds.
Get latest statuses for inbound
query{
getLatestInboundStatuses(inboundName: "Postgres DB") {
status
extraText
timestamp
}
}
Results in:
{
"data": {
"getLatestInboundStatuses": [
{
"extraText": null,
"status": "running",
"timestamp": "2021-11-08T18:43:15.303707"
}
]
}
}
Get latest statuses for outbound
Sometimes you need to know whether or not an inbound collector is online. You can do this by querying the latest statuses.
query{
getLatestOutboundStatuses(inboundName: "Postgres Redshift") {
status
extraText
timestamp
}
}
Results in:
{
"data": {
"getLatestOutboundStatuses": [
{
"extraText": null,
"status": "running",
"timestamp": "2021-11-08T18:42:58.299150"
}
]
}
}
Search
Search requires the search outbound be enabled for your database. Search gives results with the most recent change first and the oldest change last (opposite of scan).
Search by email
query{
search(outboundName:"Search", actorEmail: "[email protected]") {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Search by actor id
query{
search(outboundName:"Search", actorID: "1") {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Search limit
query{
search(outboundName:"Search", limit: 1) {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Search for row
query{
search(outboundName:"Search", table: {schema: "public", name: "table_name"}, pks:["1"]) {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Search for table
query{
search(outboundName:"Search", table: {schema: "public", name: "table_name"}) {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Search for Data Organization
query{
search(outboundName:"Search", dataOrganization: "1") {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}
Search for User Organization
query{
search(outboundName:"Search", userOrganization: "1") {
rowLsnId
relationSchema
relationName
rowPk
rowRecord
}
}