GraphQL Editor
DISCLAIMER: This page is continuously updated with new content.
Pre-requisites
Please read through the following generic GraphQL guide first.
GraphQL basics
What it is
- Query language for APIs
- Runtime for fulfilling queries with existing data
Features
- Ask exactly the data you need
- Get many resources in single request
- Single endpoint + type system: organized in terms of types and fields, not endpoints
- No-version API evolution
- Integration with own data + code
Pros
- Speed + no over-fetching/under-fetching (ask and get exactly what you need)
- Suitable for complex microservice-based systems (unified API)
- Hierarchical structure
- Data "shaping"
- Strong typing
- No "latest" version (Facebook use case)
Cons
- Query complexity can be high ⇒ system load (query depth, recursion, etc.)
- Complex caching (queries can be unpredictable, dynamic)
- Complex rate-limiting
Thinking in Graphs
With GraphQL, you can model your business domain as a "graph" by defining a schema.
Within the schema, you define:
- different types of nodes
- how they connect/relate to each other
Types may reference other types, e.g., a BGP route may reference a prefix or AS path.
You can use GQL over your current business logic (but not implement it in GraphQL).
The idea is that you treat your API as an expressive shared language, expressing "how" clients consume the data (not "what" data). GraphQL enables working with legacy data. The GQL schema should be expanded/iterated gradually and frequently.
Concepts
- Queries on objects fields, using optional (variable) arguments
- Directives for forming dynamic composite queries
- Mutations to modify server-side data
- Type system: queries/mutations, scalars, enums, interfaces, unions
- Type language: agnostic (use your favorite!)
- Queries/mutations validated and executed at run-time by GQL resolvers
- Introspection capabilities by design
Type System
Example of basic Prefixes
type:
type Prefixes {
data_source_count: Int
id: uuid
ip_version: Int
routes(
distinct_on: [routes_select_column!]
limit: Int
offset: Int
order_by: [routes_order_by!]
where: routes_bool_exp
): [routes!]!
}
Example of interface:
interface Identifiable {
id: String!
}
Example of an Autonomous System entity (AutSystem) implementing the example interface:
type AutSystem implements Identifiable {
id: String!
number: Int!
}
Subscriptions
Subscriptions are a GQL feature that allows a server to send data to its clients when a specific event happens. They are typically implemented with WebSockets. The server maintains a steady connection to its subscribed client. Subscriptions break the "Request-Response-Cycle" as follows:
- Client initially opens up a long-lived connection to the server
- Client sends a subscription query that specifies which event it is interested in
- Every time this particular event happens, the server uses the connection to push the event data to the subscribed client(s).
Best Practices
- Serve over HTTP(S) via single endpoint
GET: https://myapi/graphql?query={object{field}}
POST:
{
"query": "...",
"operationName": "...",
"variables": { "myVariable": "someValue", ... }
}
Response:
{
"data": { ... },
"errors": [ ... ]
}
- JSON syntax is typical in responses (note that specification does not require it!)
- Versioning: continuous evolution & add/deprecate objects and fields
- Nullable/non-nullable types should be explicitly defined
- Authorization: delegate to business logic layer (not the GQL layer!). Frameworks like Hasura offer appropriate support for this.
- Pagination: up to API designer (typically cursor-based)
- Batching & Caching: expose globally unique IDs for clients to use/cache on
- In general: most things besides the query contexts are kept out of the spec on purpose, providing to the developer/operator freedom to implement their own business logic!
BGPQL: A GQL API for BGP data
Please check the following sections on this topic. For simplicity, we mention here some sample primitives and associations/relationships that are part of this GQL API for BGP data.
Sample primitives:
dataSources
prefixes
autonomousSystems
peerings
routes
Sample associations/relationships:
dataSources
→ allautonomousSystems
→routes.Origin
,routes.Neighbor
,peerings.Left
,peerings.Right
prefixes
→routes.prefix
Sample query:
query MyV6Prefixes {
prefixes(
distinct_on: network
where: {
routes: {originAutonomousSystem: {number: {_eq: "50414"}}, data_source_count: {_gte: 10}},
ip_version: {_eq: 6}
} order_by: {network: asc}
) {
network
}
}
Sample response:
{
"data": {
"prefixes": [
{"network": "2a12:bc0::/48"},
{"network": "2a12:bc0:1::/48"},
{"network": "2a12:bc0:2::/48"}
]
}
}
We provide a BGPQL editor based on graphiql.
The Editor contains:
- an
Explorer
(leftmost tab), to navigate the API and form queries/mutations/subscriptions with simple point and click. - the
History
(left-inner tab) of your past queries/mutations/subscriptions. - a
Prettify
functionality for syntax beauitification. - a
Docs
link redirecting to our API reference.
You can write the queries/mutations/subscriptions directly (center tab up), input query variables and optionally tune the POST request headers used (center tab down). On the rightmost side you see the resulting JSON data after you run the query/subsctiption/mutation.
BGPQL Raw API Primitives
These can be found here. Note that the accessible primitives differ depending on you role as Viewer (read-only access) or Editor (read+write access). In the current documentation we provide a more user-friendly API description with appropriate examples.
BGPQL Entities
Looking Glass
Ingested state of the system. They correspond to the Looking Glass
page contents of the UI.
dataSources
Sources of data; a data service like RIS Live may employ 100s of dataSources
. 1-N relationships with: autonomousSystemDataSourceAssociations
, prefixDataSourceAssociations
, peeringDataSourceAssociations
, routeDataSourceAssociations
, rpkiROADataSourceAssociations
, dataSourceMetadatas
. Fields: id
, locality
(not used), selector
, data_service
.
Example query/response:
query dataSources {
dataSources {
id
selector
data_service
}
}
{
"data": {
"dataSources": [
{
"id": "e7f752ec-7847-4951-8b34-433a72e30dd6",
"selector": {
"host": "rrc15",
"peer_ip": "187.16.222.156",
"peer_asn": 264479
},
"data_service": "RIS_LIVE"
}
]
}
}
autonomousSystems
The autonomous systems collected by the BGP updates (AS paths in announcements) seen by the system. 1-N relationships with: autonomousSystemDataSourceAssociations
, routeOriginAutonomousSystems
, routeNeighborAutonomousSystems
, peeringLeftAutonomousSystems
, peeringRightAutonomousSystems
. Fields: id
, number
, data_source_count
, orig_prefixes_diff
(args: base_selector_field_name, base_selector_field_value, base_service, comp_selector_field_name, comp_selector_field_value, comp_service
).
Example query/response:
query autonomousSystems {
autonomousSystems {
number
data_source_count
id
}
}
{
"data": {
"autonomousSystems": [
{
"number": 20080,
"data_source_count": 3,
"id": "d54e0509-9f64-4123-a879-54e9852a8a48"
}
]
}
}
autonomousSystemDataSourceAssociations
Data source - AS associations. 1-1 relationships with: autonomousSystem
, dataSource
. Fields: id
, data_time
.
Example query/response:
query autonomousSystemDataSourceAssociations {
autonomousSystemDataSourceAssociations {
data_time
id
dataSource {
id
}
autonomousSystem {
id
}
}
}
{
"data": {
"autonomousSystemDataSourceAssociations": [
{
"data_time": "2023-02-16T22:20:39.49+00:00",
"id": "2a2c044b-e946-4abe-8b9a-0752b5a583e1",
"dataSource": {
"id": "d1d0af52-3e83-4897-b9a4-4a6d3c79a2bc"
},
"autonomousSystem": {
"id": "596cc059-a99d-4779-9910-0c841645ffb2"
}
}
]
}
}
prefixes
The prefixes collected by the BGP updates seen by the system. 1-N relationships with prefixDataSourceAssociations
, routes
. Fields: id
, configured_prefix_best_match
, data_source_count
, ip_version
(auto-generated), mask_length
(auto-generated), network
, is_sub_prefix
(args: network
), is_sub_prefix_multiple
(args: networks
), as_paths_diff
(args: base_service, comp_service, end_asn
).
Example query/response:
query Prefixes {
prefixes {
configured_prefix_best_match
data_source_count
id
ip_version
mask_length
network
}
}
{
"data": {
"prefixes": [
{
"configured_prefix_best_match": "",
"data_source_count": 126,
"id": "f8d2a4f8-04ba-4b5f-8312-63b31cfd9a7d",
"ip_version": 6,
"mask_length": 48,
"network": "2a12:bc0::/48"
}
]
}
}
prefixDataSourceAssociations
Data source - prefix associations. 1-1 relationships with: prefix
, dataSource
. Fields: id
, withdrawn
, data_time
.
Example query/response:
query PrefixDataSourceAssociations {
prefixDataSourceAssociations {
data_time
withdrawn
prefix {
id
}
dataSource {
id
}
}
}
{
"data": {
"prefixDataSourceAssociations": [
{
"data_time": "2023-03-02T06:51:59+00:00",
"withdrawn": false,
"prefix": {
"id": "cf931693-8a38-4d11-8bd5-5c9fc00e067a"
},
"dataSource": {
"id": "e401023b-3328-4804-8ccd-6f892bb8ec44"
}
}
]
}
}
peerings
The autonomous system peerings (AS-level) collected by the BGP updates (AS paths in announcements) seen by the system. Note that for a path of the form AS1 AS2 AS3
, with AS3
as the origin AS, we derive two peerings with the following directions: AS3->AS2
, AS2->AS1
. 1-1 relationships with: autonomousSystem
. 1-N relationships with: peeringDataSourceAssociations
. Fields: id
, data_source_count
.
Example query/response:
query Peerings {
peerings {
data_source_count
id
leftAutonomousSystem {
number
}
rightAutonomousSystem {
number
}
}
}
{
"data": {
"peerings": [
{
"data_source_count": 92,
"id": "2d91eb81-4a84-4d57-9868-152549a7f90a",
"leftAutonomousSystem": {
"number": 50414
},
"rightAutonomousSystem": {
"number": 20473
}
}
]
}
}
peeringDataSourceAssociations
Data source - peering associations. 1-1 relationships with: peering
, dataSource
. Fields: id
, data_time
.
Example query/response:
query PeeringDataSourceAssociations {
peeringDataSourceAssociations {
id
data_time
peering {
id
}
dataSource {
id
}
}
}
{
"data": {
"peeringDataSourceAssociations": [
{
"id": "5a65fbde-06ae-42f3-b107-753f62adb398",
"data_time": "2023-03-02T03:58:36.84+00:00",
"peering": {
"id": "727733c1-f07d-45e9-a8a3-65f235d8c458"
},
"dataSource": {
"id": "9d7703e5-e5fc-4797-a6cd-b45eee0b7bce"
}
}
]
}
}
routes
The routes correlating prefixes, autonomous systems, paths and other update info collected by the BGP updates seen by the system. 1-1 relationships with: autonomousSystem
, prefix
. 1-N relationships with: routeDataSourceAssociations
. Fields: id
, data_source_count
, as_path
, rpki_status
.
Example query/response:
query Routes {
routes {
id
data_source_count
as_path
prefix {
network
}
originAutonomousSystem {
number
}
neighborAutonomousSystem {
number
}
rpki_status
}
}
{
"data": {
"routes": [
{
"id": "394fcad8-720d-4162-8a19-ba169efe4fe4",
"data_source_count": 2,
"as_path": "57695 60068 2914 3356 3908 721 27064 5927",
"prefix": {
"network": "2608:140:c::/48"
},
"originAutonomousSystem": {
"number": 5927
},
"neighborAutonomousSystem": {
"number": 27064
},
"rpki_status": "not-found"
}
]
}
}
routeDataSourceAssociations
Data source - route associations. 1-1 relationships with: route
, dataSource
. Fields: id
, communities
, data_time
.
Example query/response:
query RouteDataSourceAssociations {
routeDataSourceAssociations {
communities
data_time
id
route {
id
}
dataSource {
id
}
}
}
{
"data": {
"routeDataSourceAssociations": [
{
"communities": [
"25091:41252",
"65300:20144"
],
"data_time": "2023-03-02T09:00:20+00:00",
"id": "96d822e0-17d2-4ea3-878f-aeff84be0050",
"route": {
"id": "ca0b7a85-bce6-4dd0-8c48-75426bbd6638"
},
"dataSource": {
"id": "7d129b0e-a0c3-4829-91cf-57ae283e1d7f"
}
}
]
}
}
rpkiROAs
RPKI ROAs downloaded from RPKI repositories. 1-N relationships with: rpkiROADataSourceAssociations
. Fields: id
, autonomous_system_number
, data_source_count
, expiry_time
, ip_version
(auto-generated), mask_length
(auto-generated), max_length
, network
.
Example query/response:
query RPKIROAs {
rpkiROAs {
autonomous_system_number
data_source_count
expiry_time
id
ip_version
mask_length
max_length
network
}
}
{
"data": {
"rpkiROAs": [
{
"autonomous_system_number": 16509,
"data_source_count": 1,
"expiry_time": "0001-01-01T00:00:00+00:00",
"id": "645aafc8-423b-4ee4-98b5-5ba65fad4221",
"ip_version": 4,
"mask_length": 24,
"max_length": 24,
"network": "2.255.190.0/24"
}
]
}
}
rpkiROADataSourceAssociations
Data source - RPKI ROA associations. 1-1 relationships with: rpki_roa
, dataSource
. Fields: id
, data_time
.
Example query/response:
query RPKIROADataSourceAssociations {
rpkiROADataSourceAssociations {
data_time
id
dataSource {
id
}
rpkiROA {
id
}
}
}
{
"data": {
"rpkiROADataSourceAssociations": [
{
"data_time": "2023-02-09T13:31:51+00:00",
"id": "475ffd6f-93cd-4271-a1be-bb96104d1b8f",
"dataSource": {
"id": "433de726-02b4-4431-9366-bf5d4653d0c9"
},
"rpkiROA": {
"id": "645aafc8-423b-4ee4-98b5-5ba65fad4221"
}
}
]
}
}
dataSourceMetadatas
TBD
Configuration/Setup
Configuration and setup entities for configuring the system. They correspond to the Setup
page contents of the UI.
alertReceiverTypes
Read-only available types of alert receivers, with their internal IDs and external labels. Currently available: Email
, Slack
(via Email). 1-N relationship with alertSubscriptions
. Fields: id
, label
.
Example query/response:
query alertReceiverTypes {
alertReceiverTypes {
id
label
}
}
{
"data": {
"alertReceiverTypes": [
{
"id": "email",
"label": "Email"
},
{
"id": "slack",
"label": "Slack"
}
]
}
}
alertSeverities
Read-only available severities of alerts, with their internal IDs and external labels. Currently available: warning
, critical
. 1-N relationship with alertSubscriptions
. Fields: id
, label
.
Example query/response:
query alertSeverities {
alertSeverities {
id
label
}
}
{
"data": {
"alertSeverities": [
{
"id": "warning",
"label": "warning"
},
{
"id": "critical",
"label": "critical"
}
]
}
}
alertTypes
Read-only available types of alerts, with their internal IDs and external labels. Currently available: Exact Prefix Hijack
, Sub-Prefix Hijack
, Route Leak
, New Neighbor
, Neighbor Leak/Hijack
, Squatting
, RPKI-Invalid Detection
, RPKI-Invalid Announcement
, RPKI-Invalid Propagation
, RPKI-NotFound Propagation
, Bogon (Exact-)Prefix
,Bogon (Sub-)Prefix
, Bogon AS
, AS Path Comparison
, Prefix Comparison
, Custom
. Fields: id
, label
.
Example query/response:
query alertTypes {
alertTypes {
id
label
}
}
{
"data": {
"alertTypes": [
{
"id": "unexpected_originated_prefixes",
"label": "Route Leak"
},
{
"id": "unexpected_neighbor_prefix",
"label": "Neighbor Leak/Hijack"
},
{
"id": "as_origin_violation_exact",
"label": "Exact Prefix Hijack"
},
{
"id": "as_origin_violation_sub",
"label": "Sub-Prefix Hijack"
},
{
"id": "sub_prefix",
"label": "Possible Sub-prefix Hijack"
},
{
"id": "squatting",
"label": "Squatting"
},
{
"id": "rpki_invalid_detect",
"label": "RPKI-Invalid Detection"
},
{
"id": "rpki_invalid_announce",
"label": "RPKI-Invalid Announcement"
},
{
"id": "rpki_invalid_propagate",
"label": "RPKI-Invalid Propagation"
},
{
"id": "rpki_not_found_propagate",
"label": "RPKI-NotFound Propagation"
},
{
"id": "unexpected_peering",
"label": "New Neighbor"
},
{
"id": "bogon_as",
"label": "Bogon AS"
},
{
"id": "as_path_diffs",
"label": "AS Path Comparison"
},
{
"id": "prefix_diffs",
"label": "Prefix Comparison"
},
{
"id": "custom",
"label": "Custom"
},
{
"id": "bogon_prefix_exact",
"label": "Bogon (Exact-)Prefix"
},
{
"id": "bogon_prefix_sub",
"label": "Bogon (Sub-)Prefix"
}
]
}
}
alertSubscriptions
Configured alert rule GQL subscriptions. 1-1 relationship with alertReceiverType
, alertSeverity
, alertType
. Fields: id
, name
, type
, severity
, description
, query
, vars
, fire_alert_regex
, receiver_type
,receiver_endpoint
, activation_time
.
Example query/response:
query alertSubscriptions {
alertSubscriptions {
id
fire_alert_regex
description
activation_time
name
query
receiver_endpoint
receiver_type
severity
type
vars
}
}
{
"data": {
"alertSubscriptions": [
{
"id": "ecb0b70a-466f-49bd-b41a-5dd9542d7317",
"fire_alert_regex": "^.*prefixes.*\\[.*network.*$",
"description": "Unexpected prefixes in the list of prefixes that are announced by configured ASes",
"activation_time": "2023-02-17T15:10:00.351226+00:00",
"name": "B-Root USC ISI Route Leak",
"query": "subscription RouteLeak($asn: bigint!, $prefixes: [cidr!] = [], $ds_thres: Int!) {prefixes(where: {routes: {originAutonomousSystem: {number: {_eq: $asn}}}, network: {_nin: $prefixes}, data_source_count: {_gte: $ds_thres} } order_by: {network: asc}) {network }}",
"receiver_endpoint": "[email protected]",
"receiver_type": "email",
"severity": "critical",
"type": "unexpected_originated_prefixes",
"vars": {
"asn": "394353",
"ds_thres": "1",
"prefixes": [
"192.228.79.0/24",
"199.9.14.0/23",
"199.9.14.0/24",
"199.9.15.0/24",
"2001:500:200::/44",
"2001:500:200::/48",
"2001:500:201::/48",
"2001:500:204::/48",
"2001:500:205::/48",
"2001:500:206::/48",
"2001:500:207::/48",
"2001:500:208::/48",
"2001:500:209::/48",
"2001:500:84::/48"
]
}
}
]
}
}
configuredAutonomousSystems
Read-only configured AS filters, populated by writable manuallyConfiguredAutonomousSystems
. Fields: number
, data_service
(not used).
Example query/response:
query configuredAutonomousSystems {
configuredAutonomousSystems {
number
}
}
{
"data": {
"configuredAutonomousSystems": [
{
"number": 50414
}
]
}
}
configuredPrefixes
Read-only configured prefix filters, populated by writable manuallyConfiguredPrefixes
. Fields: network
, ip_version
(auto-generated), mask_length
(auto-generated), data_service
(not used).
Example query/response:
query configuredPrefixes {
configuredPrefixes {
ip_version
mask_length
network
}
}
{
"data": {
"configuredPrefixes": [
{
"ip_version": 4,
"mask_length": 24,
"network": "192.203.230.0/24"
}
]
}
}
configuredDataServices
Configured data services. Fields: configuration
(not used), id
, data_service
, data_source_selector_fields
(not used), enabled
, filter_on_autonomous_system
, filter_on_data_source
(not used), filter_on_prefix
.
Example query/response:
query configuredDataServices {
configuredDataServices {
id
filter_on_prefix
filter_on_autonomous_system
enabled
data_service
}
}
{
"data": {
"configuredDataServices": [
{
"id": "5615dc61-a5c3-4447-8909-f48b51abd97a",
"filter_on_prefix": "any",
"filter_on_autonomous_system": "origin",
"enabled": true,
"data_service": "RPKI"
},
{
"id": "b9612cdd-80d5-40e8-be91-3ed93ce788e9",
"filter_on_prefix": "any",
"filter_on_autonomous_system": "origin",
"enabled": true,
"data_service": "BGP_ROUTER"
},
{
"id": "d4d6deb5-a705-4368-a4e7-b0b03fe075a1",
"filter_on_prefix": "any",
"filter_on_autonomous_system": "origin",
"enabled": true,
"data_service": "CODEBGP_MONITOR"
},
{
"id": "20991c99-ba10-4395-bb11-87f1a5a377fc",
"filter_on_prefix": "any",
"filter_on_autonomous_system": "origin",
"enabled": true,
"data_service": "RIS_LIVE"
}
]
}
}
configuredDataSources
[NOT USED] Read-only configured data source filters, populated by writable manuallyConfiguredDataSources
. Fields: data_service
, selector
.
manuallyConfiguredAutonomousSystems
Manually configured AS filters. Fields: id
, number
, reject
(not used).
Example query/response:
query manuallyConfiguredAutonomousSystems {
manuallyConfiguredAutonomousSystems {
id
number
}
}
{
"data": {
"manuallyConfiguredAutonomousSystems": [
{
"id": "d8809422-e1a0-4d41-a752-0473e954ff34",
"number": 50414
}
]
}
}
manuallyConfiguredPrefixes
Manually configured prefix filters. Fields: id
, ip_version
(auto-generated), mask_length
(auto-generated), network
, reject
(not used).
Example query/response:
query manuallyConfiguredPrefixes {
manuallyConfiguredPrefixes {
ip_version
mask_length
network
id
}
}
{
"data": {
"manuallyConfiguredPrefixes": [
{
"ip_version": 4,
"mask_length": 24,
"network": "212.46.55.0/24",
"id": "e37f385a-6ada-4b81-872c-b69010277412"
}
]
}
}
manuallyConfiguredDataSources
[NOT USED] Manually configured data source filters. Fields: id
, reject
, data_service
, selector
.
Filtering via where
Queries/subscriptions/mutations can target specific data by using where
filters.
Example:
subscription NeighborsToWhichPrefixIsAnnounced($asns: [bigint!] = [], $prefix: cidr!) {
routes(
where: {originAutonomousSystem: {number: {_in: $asns}}, prefix: {network: {_eq: $prefix}}}
) {
originAutonomousSystem {
number
}
neighborAutonomousSystem {
number
}
routeDataSourceAssociations {
communities_string
}
}
}
You can also form more complex BGPQL queries that are parameterized accordingly, as follows.
What prefixes from that AS are visible from my AS?
subscription PrefixesFromOriginASNVisibleFromASN($originASNRegex: String!, $visibleFromASNRegex: String!) {
prefixes(
where: {routes: {_and: [{as_path: {_regex: $originASNRegex}}, {as_path: {_regex: $visibleFromASNRegex}}]}}
order_by: {network: asc}
) {
network
}
}
Sample variables:
{"originASNRegex":"( |^)2149$","visibleFromASNRegex":"( |^)3557( |$)"}
Which prefixes leak visibly from my AS?
subscription LeakedPrefixesMyASNOriginates($asn: bigint!, $prefixes: [cidr!] = [], $ds_thres: Int!) {
prefixes(where: {routes: {originAutonomousSystem: {number: {_eq: $asn}}}, network: {_nin: $prefixes}, data_source_count: {_gte: $ds_thres} } order_by: {network: asc}) {
network
}
}
Sample variables:
{asn: 65001, prefixes: ["139.91.0.0/16"], ds_thres: 1}
What are the RPKI-invalids my AS propagates?
subscription RPKIInvalidPrefixesPropagatedByMyASNs($asn_regex: String, $rpki_status: String!) {
routes(
order_by: {as_path: asc, prefix: {network: asc}}
where: {as_path: {_iregex: $asn_regex}, rpki_status: {_eq: $rpki_status}}
) {
prefix {
network
}
as_path
}
}
Sample variables:
{asn_regex: "( 8522 )|(^8522 )|( 8522$)|(^8522$)", rpki_status: "invalid"}
Which paths towards my prefixes contain ASes that should not be present?
subscription ASPathPresence($prefixes: [String!] = [], $asn_present_regex: String!) {
routes(
where: {prefix: {configured_prefix_best_match: {_in: $prefixes}}, as_path: {_iregex: $asn_present_regex}}
order_by: {as_path: asc, prefix: {network: asc}}
) {
prefix {
network
}
as_path
}
}
Sample variables:
{prefixes: ["139.91.0.0/16"],asn_present_regex:( 8522 )|(^8522 )|( 8522$)|(^8522$)"}
Aggregates
Aggregate functions on entities.
Format: <entity>Aggregate
.
Fields: nodes
(with sub-fields same as <entity>
), aggregate
(with functions such as count
, min
, max
, avg
, etc.)
Example query/response:
query dataSourcesAggregate {
dataSourcesAggregate {
aggregate {
count
}
}
}
{
"data": {
"dataSourcesAggregate": {
"aggregate": {
"count": 5752
}
}
}
}