Live Queries are GraphQL queries created once and then remain active, monitoring for changes perpetually. Whenever a change is detected, the latest result is stored / cached for easy retrieval. For example, you might create one that monitors for new sites added to an org, or when a new device is detected at a building.
While there are varied reasons to use a live query, like caching the results of a complicated query for faster response times, combining with a webhook is the most common and useful. When you want the result of a query to be sent to you whenever a change is detected, instead of polling for results, you can connect a live query to a webhook and get the latest result pushed to an endpoint of your choosing.
Live queries only detect changes to the Mapped graph, meaning only information pertaining to the nodes (devices / points), edges (relationships between devices, points, and places), or properties (like place / location data) can be accessed. In other words, a live query is only going to return data about the places and things in your org. Data like org users, tokens generated by those users, which connectors are configured, what gateways are live, areas that feed or interact with the graph but are not part of the graph itself, all are inaccessible to a live query.
We'll go through the process to create, view, update and delete live queries first, then we'll go into the process to combine one with a webhook in order to get results sent to an endpoint.
There are two methods to create a live query - the first is to use createLiveQuery, where you just provide a unique name and the query you want to monitor:
Request ResponseCopy1 2 3 4 5 6 7 8 9 10 11 12 13 14
mutation { createLiveQuery( input: { liveQuery: { name: "Site Update", query: "{sites {name id }}" } } ) { liveQuery { id name dateCreated query } } }
A second way to create a live query is to use a directive syntax called @Live. This option allows you to create a live query at the same time you make the request you want monitored.
When using a directive, you'll also need to preface the request with query. Since directives can be used with both queries and mutations, here you need to be explicit, whereas in our other query examples throughout the docs, the request is assumed to be a query by default.
Request ResponseCopy1 2 3 4 5 6
query @live(name: "Alt Site Update Query") { sites { id name } }
You can view all the existing live queries by calling liveQueries and listing out the fields you want to see. At the same time, you can also return the last change value detected using the lastResult field:
Request ResponseCopy1 2 3 4 5 6 7 8 9
{ liveQueries { dateCreated id name query lastResult } }
If you want to look at the lastResult for one particular live query, just include a filter for the ID:
Request ResponseCopy1 2 3 4 5 6 7 8 9
{ liveQueries(filter: {id: {eq: "LVQ7q4jCHXwvCwFNYUMRkAbC1"}}) { dateCreated id name query lastResult } }
Review the LiveQuery entry of the API Reference for more fields you can return, like lastErrorDate for troubleshooting.
If you want to update a live query, you would use updateLiveQuery; currently only the name can be updated:
Request ResponseCopy1 2 3 4 5 6 7 8 9 10 11 12 13
mutation { updateLiveQuery( input: { liveQuery: { id: "LVQ7q4jCHXwvCwFNYUMRkAbC1", name: "Site Update Old" } } ) { liveQuery { id name dateUpdated } } }
If you want a live query to take a break, but don't want to remove it entirely, you can use the pause/resume functionality. The code is super simple - just pass the live query id to either pauseLiveQuery or resumeLiveQuery.
To pause a live query:
Request ResponseCopy1 2 3 4 5
mutation { pauseLiveQuery(input: { id: "LVQ7q4jCHXwvCwFNYUMRkAbC1" }) { _ } }
To resume a live query:
Request ResponseCopy1 2 3 4 5
mutation { resumeLiveQuery(input: { id: "LVQ7q4jCHXwvCwFNYUMRkAbC1" }) { _ } }
To view the status of a live query:
Request ResponseCopy1 2 3 4 5 6 7
{ liveQueries(filter: {id: {eq: "LVQ7q4jCHXwvCwFNYUMRkAbC1"}}) { id name status } }
If you want to remove a live query, just call deleteLiveQuery and pass the ID of the one you want deleted:
Request ResponseCopy1 2 3 4 5
mutation { deleteLiveQuery(input: { id: "LVQ7q4jCHXwvCwFNYUMRkAbC1" }) { _ } }
Now we'll walk through the steps to connect a live query with a webhook. You'll need the live query created first, in order to monitor for the for the data you want - in this example, we'll create a query to track the time series data for a particular point using the @Live directive mentioned earlier:
Request ResponseCopy1 2 3 4 5 6
query @live(name: "Webhook Site Update Query") { sites { id name } }
Next, we'll create the webhook to subscribe to the new live query, so every time a change is detected, we'll get the results sent to our endpoint:
Request ResponseCopy1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
mutation { createWebhookTarget( input: { target: { name: "Live Query Subscription" eventFilters: { jsonExpressionFilter: { jsonPathExpression: "@.source == '//com.mapped/orgs/ORG8Si1dkzGEYZgxrR4ZYAbCD/liveQueries/LVQCJcMTCrz86gs8UteKroy34'" } } httpTarget: { method: POST targetUri: "https://example.com/d123456abcde" auth: { noAuth: true } } maxRetry: 10 enabled: true } } ) { target { id name eventFilters { jsonExpressionFilter { jsonPathExpression } } httpTarget { auth { noAuth } method targetUri } maxRetry enabled } } }
Once created, the above webhook will send a POST to the endpoint https://example.com/d123456abcde every time a new site is added to the org. The received data will be formatted as JSON, and will include the live query ID as well for correlation if you have more than one live query running to the same webhook endpoint:
Copy1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{ "lastResult": { "sites": [ { "id": "SITEA2yCZ58ZpJsE7hH3Sj52CP", "name": "OG Site" }, { "id": "SITETeZNmbxTZKbN6ArdANbyvX", "name": "New Site" }, { "id": "SITEK8qWoMJddAgv9SCwJtoYfx", "name": "New New Site" } ] }, "liveQueryId": "LVQCJcMTCrz86gs8UteKroy34" }
Check out the Webhook Guide for more in depth instructions on creating and working with webhooks.