Behaviour: Querying
←Behaviour - Registration · Index↑ · Data Model→
The Query API provides a read-only interface to the Nodes and their sub-resources which are currently held in the registry. Browsing of the Query API may be performed via the RESTful API, or by using the websocket protocol (RFC 6455) which is suggested for most applications.
Creating a Websocket subscription
In order to connect to a websocket, a client must first request a subscription of a particular type and with particular query parameters by performing a POST as defined in the Query API subscriptions documentation. Use of GET requests to find existing suitable websocket connections is strongly discouraged.
There is no mandated URL base path for servers to use when creating websocket connections. Instead clients should observe the value of ‘ws_href’ which is returned by their subscription request in order to identify what to connect to.
Websockets created for specific clients will be cleaned up automatically if they disconnect.
Connection upgrade procedures permitting an existing HTTP query to transition to a websocket are not currently supported, but may be in the future.
Query API Behaviour
Upon receiving a request for a new subscription, the Query API should identify whether it already has any websockets open which provide for the requested query. If a websocket exists, the ‘subscription’ object representing it may be returned to the user. If a relevant websocket does not exist a new one should be created.
In normal operation, once a websocket has no more clients subscribed to it the Query API may automatically remove it and its corresponding HTTP-advertised subscription object. The Query API MUST NOT acknowledge HTTP DELETE requests for websockets running in this ‘non-persistent’ mode, instead issuing an HTTP 403 response.
If a ‘persistent’ websocket has been requested by the client, this must not be cleaned up automatically by the Query API, even if all consuming clients have disconnected. The user may request closing of this socket by issuing an HTTP DELETE.
Websocket Protocol
Using data Grains, the websocket protocol provides a client with the current state of the contents of the registry at the time of subscription. It subsequently notifies clients of any changes.
Note that the Source ID used in the following examples references the Query API instance. The Flow ID then corresponds to the subscription ID created via the /subscriptions HTTP resource.
Each Grain may contain one or more objects in its ‘data’ array. Each object identifies a change to a single Source, Flow or other resource as identified by the ‘topic’.
A schema for the Grain metadata described below is available here.
Resource(s) Added Event
Event data containing only a “post” attribute signifies creation of a resource.
{
"grain_type": "event",
"source_id": <id_of_query_api_instance>,
"flow_id": "e223e6f3-de75-4855-bd19-b83774e31689",
"origin_timestamp": <ts_secs>:<ts_nsecs>,
"sync_timestamp": <ts_secs>:<ts_nsecs>,
"creation_timestamp": <ts_secs>:<ts_nsecs>,
"rate": {
"numerator": 0,
"denominator": 1
},
"duration": {
"numerator": 0,
"denominator": 1
},
"grain": {
"type": "urn:x-nmos:format:data.event",
"topic": "/flows/",
"data": [
{
"path": "b58aae65-1913-4f7b-aae2-2377446dd639",
"post": {
"id": "b58aae65-1913-4f7b-aae2-2377446dd639",
"label": "my_flow_name",
"description": "my flow description",
"source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
"format": "urn:x-nmos:format:video"
}
},
...
]
}
}
Resource(s) Removed Event
Event data containing only a “pre” attribute signifies deletion of a resource.
{
"grain_type": "event",
"source_id": <id_of_query_service_instance>,
"flow_id": "e223e6f3-de75-4855-bd19-b83774e31689",
"origin_timestamp": <ts_secs>:<ts_nsecs>,
"sync_timestamp": <ts_secs>:<ts_nsecs>,
"creation_timestamp": <ts_secs>:<ts_nsecs>,
"rate": {
"numerator": 0,
"denominator": 1
},
"duration": {
"numerator": 0,
"denominator": 1
},
"grain": {
"type": "urn:x-nmos:format:data.event",
"topic": "/flows/",
"data": [
{
"path": "b58aae65-1913-4f7b-aae2-2377446dd639",
"pre": {
"id": "b58aae65-1913-4f7b-aae2-2377446dd639",
"label": "my_flow_name",
"description": "my flow description",
"source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
"format": "urn:x-nmos:format:video"
}
},
...
]
}
}
Resource(s) Modified Event
Event data containing both “pre” and “post” attributes signifies modification of a resource. All attributes of the resource must be specified (i.e. not just those that have changed).
{
"grain_type": "event",
"source_id": <id_of_query_service_instance>,
"flow_id": "e223e6f3-de75-4855-bd19-b83774e31689",
"origin_timestamp": <ts_secs>:<ts_nsecs>,
"sync_timestamp": <ts_secs>:<ts_nsecs>,
"creation_timestamp": <ts_secs>:<ts_nsecs>,
"rate": {
"numerator": 0,
"denominator": 1
},
"duration": {
"numerator": 0,
"denominator": 1
},
"grain": {
"type": "urn:x-nmos:format:data.event",
"topic": "/flows/",
"data": [
{
"path": "b58aae65-1913-4f7b-aae2-2377446dd639",
"pre": {
"id": "b58aae65-1913-4f7b-aae2-2377446dd639",
"label": "my_flow_name",
"description": "my flow description",
"source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
"format": "urn:x-nmos:format:video"
},
"post": {
"id": "b58aae65-1913-4f7b-aae2-2377446dd639",
"label": "my_new_flow_name",
"description": "my new flow description",
"source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
"format": "urn:x-nmos:format:video"
}
},
...
]
}
}
Resource(s) Unchanged (Sync) Event
Event data containing both “pre” and “post” where the contents of “pre” and “post” are identical. This is used in initial synchronisation messages to ensure the client has received all data for a given topic.
{
"grain_type": "event",
"source_id": <id_of_query_service_instance>,
"flow_id": "e223e6f3-de75-4855-bd19-b83774e31689",
"origin_timestamp": <ts_secs>:<ts_nsecs>,
"sync_timestamp": <ts_secs>:<ts_nsecs>,
"creation_timestamp": <ts_secs>:<ts_nsecs>,
"rate": {
"numerator": 0,
"denominator": 1
},
"duration": {
"numerator": 0,
"denominator": 1
},
"grain": {
"type": "urn:x-nmos:format:data.event",
"topic": "/flows/",
"data": [
{
"path": "b58aae65-1913-4f7b-aae2-2377446dd639",
"pre": {
"id": "b58aae65-1913-4f7b-aae2-2377446dd639",
"label": "my_flow_name",
"description": "my flow description",
"source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
"format": "urn:x-nmos:format:video"
},
"post": {
"id": "b58aae65-1913-4f7b-aae2-2377446dd639",
"label": "my_flow_name",
"description": "my flow description",
"source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
"format": "urn:x-nmos:format:video"
}
},
{
"path": "e759c3f0-8eed-4344-932a-5eb1c40a2d41",
"pre": {
"id": "e759c3f0-8eed-4344-932a-5eb1c40a2d41",
"label": "another_flow_name",
"description": "another flow description",
"source_id": "d7f43929-30c7-4847-a0f8-0242b82002d8",
"format": "urn:x-nmos:format:audio"
},
"post": {
"id": "e759c3f0-8eed-4344-932a-5eb1c40a2d41",
"label": "another_flow_name",
"description": "another flow description",
"source_id": "d7f43929-30c7-4847-a0f8-0242b82002d8",
"format": "urn:x-nmos:format:audio"
}
},
...
]
}
}
Handling Query Parameters
Websocket subscriptions support query parameters in the same way as the corresponding REST API endpoints. Care should be taken to ensure that clients are informed when resources begin to or no longer match a given query parameter. For example:
- If a Flow (or other resource) has a ‘tag’ removed causing it to no longer match the query parameters for a websocket subscription, the client must be issued a ‘Resource Removed Event’ as if this resource had been deleted from the registry.
- If a Flow (or other resource) has a ‘tag’ added causing it to match a query parameter where it didn’t match them previously, the client must be issued a ‘Resource Added Event’ as if this resource had been freshly created in the registry.
Referential Integrity
API clients should be aware of the following potential issues when interacting with the ‘senders’ and ‘receivers’ arrays present within Device resources. Use of these arrays is discouraged.
- Devices MAY be registered with UUIDs of the Senders and Receivers attached to the Device, in the “senders” and “receivers” array properties, even if those Senders/Receivers have not yet been registered themselves.
- Senders and Receivers attached to Devices MAY be omitted from the Device’s “senders” and “receivers” array properties. Consumers of the Node/Query APIs SHOULD instead discover attached Senders/Receivers by filtering Senders and Receivers on “device_id”.