Drova chose GraphQL because it allows us to be very specific about the data we want, saving time and reducing unnecessary information. It's like ordering exactly what you need from a menu, whereas traditional REST APIs might serve you a full meal. With GraphQL, we can bundle many requests into one, making it more efficient to get the data we want
For the Drova GRC Public Schema, you can obtain the latest version of the public schema by downloading DrovaGRC-PublicSchema.json
Alternatively, you can perform introspection directly against the GraphQL API using Postman.
Connections enable you to retrieve related objects within a single GraphQL query. This contrasts with REST APIs, where multiple calls might be necessary. Visualise a graph with interconnected dots; the dots are nodes, and the lines connecting them are edges. A connection defines the relationships between these nodes.
Edges represent the connections between nodes. When querying a connection, you navigate through its edges to access the associated nodes. Each edges field includes a node field and a cursor field, with cursors serving for pagination.
Node serves as a general term for an object. You can either directly access a node or explore related nodes through a connection.
Example of how to query records inside your Drova GRC site
POST: https://api.drova.com/graphql
Headers
Authorization: Bearer [access_token]
How to get access token Drova GRC API documentation
Arguments
tenantId: Your GRC site code.
first: get the number of nodes
GraphQL query
// sample get top 3 events in the site
{
grcWebsite(tenantId: "YOUR_GRC_SITE_CODE") {
events(first: 3) {
totalCount
edges {
cursor
node {
id
title
}
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
}
}
}
}
JSON response
{
"data": {
"grcWebsite": {
"events": {
"totalCount": 2006,
"edges": [
{
"cursor": "aW50ZXJuYWxJZD0x",
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDox",
"title": "Compliance Breach"
}
},
{
"cursor": "aW50ZXJuYWxJZD0y",
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDoy",
"title": "Customer disputing management of information"
}
},
{
"cursor": "aW50ZXJuYWxJZD0z",
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDoz",
"title": "Privacy Data Breach"
}
}
],
"pageInfo": {
"endCursor": "aW50ZXJuYWxJZD0z",
"hasNextPage": true,
"hasPreviousPage": false,
"startCursor": "aW50ZXJuYWxJZD0x"
}
}
}
}
}
In GraphQL, every connection provides a PageInfo
object that facilitates cursor-based pagination. The PageInfo
object typically consists of the following fields:
Field | Type | Description |
---|---|---|
| Boolean | This field indicates whether there are any results in the connection preceding the current page. |
| Boolean | This field signifies whether there are any results in the connection following the current page |
| string | The |
| string | The |
Drova GRC APIs offer forward pagination, and this is accomplished by using the following connection variables:
Field | Type | Description |
---|---|---|
| integer | Defines the maximum number of |
| string | The cursor indicating where to start fetching data from the connection, enabling you to continue retrieving data after that specific point. |
Drova GraphQL APIs support backward pagination using the following connection variables
Field | Type | Description |
---|---|---|
| integer | This variable specifies the maximum number of |
| string | The cursor that indicates where in the connection you want to begin fetching data when moving backward. It serves as a reference point, allowing you to continue retrieving data from the connection before the specified cursor |
By utilising these variables in your GraphQL queries, you can effectively implement forward/backward pagination to navigate through a set of results in Drova GraphQL APIs in the right order.
Here's an example of how to retrieve the next 3 nodes from the second page using GraphQL with forward pagination
POST: https://api.drova.com/graphql
Headers
Authorisation: Bearer [access_token]
Arguments
tenantId: Your GRC site code
first: get the number of nodes
after: The cursor of the last item of the previous response.
GraphQL query
{
grcWebsite(tenantId: "YOUR_GRC_SITE_CODE") {
events(first: 3, after: "aW50ZXJuYWxJZD0z") {
totalCount
edges {
cursor
node {
id
title
}
}
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
}
}
}
}
JSON response
{
"data": {
"grcWebsite": {
"events": {
"totalCount": 2006,
"edges": [
{
"cursor": "aW50ZXJuYWxJZD00",
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo0",
"title": "Privacy breach - statement issue"
}
},
{
"cursor": "aW50ZXJuYWxJZD01",
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo1",
"title": "Privacy breach - identification error"
}
},
{
"cursor": "aW50ZXJuYWxJZD02",
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo2",
"title": "Data Breach"
}
}
],
"pageInfo": {
"endCursor": "aW50ZXJuYWxJZD02",
"hasNextPage": true,
"hasPreviousPage": false,
"startCursor": "aW50ZXJuYWxJZD00"
}
}
}
}
}
Node query is the generic query to retrieve any object details based on a given Global ID; the Global ID is the unique ID of the record across the site, returning along with each node's connection API.
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo2", // Dr GRC Global ID
"title": "Data Breach"
}
You can retrieve the object details based on that ID as an example bellow
POST: https://api.drova.com/graphql
Headers
Authorisation: Bearer [access_token]
Arguments
id: the Global ID of record.
GraphQL query
{
node(id: "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo2") {
id
... on GrcEvent {
dateClosed
elapsedTime
eventDate
id
isBreach
lossAmount
permissions
recordNumber
remedialCost
reportedDate
riskRating
statusDescription
title
}
}
}
JSON response
{
"data": {
"node": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo2",
"dateClosed": "2021-10-31T22:07:31.203Z",
"elapsedTime": 1333,
"eventDate": "2018-03-08T00:04:11.233Z",
"isBreach": false,
"lossAmount": 0,
"permissions": [],
"recordNumber": "RDB000004",
"remedialCost": 0,
"reportedDate": "2018-03-08T00:07:18.373Z",
"riskRating": "Extreme",
"statusDescription": "Unknown",
"title": "Data Breach"
}
}
}
You also can receive details of multiple records at once
GraphQL query
{
record1: node(id: "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo2") {
id
... on GrcEvent {
dateClosed
elapsedTime
eventDate
id
isBreach
lossAmount
permissions
recordNumber
remedialCost
reportedDate
riskRating
statusDescription
title
}
}
record2: node(id: "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo0") {
id
... on GrcEvent {
dateClosed
elapsedTime
eventDate
id
isBreach
lossAmount
permissions
recordNumber
remedialCost
reportedDate
riskRating
statusDescription
title
}
}
}
JSON response
{
"data": {
"record1": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo2",
"dateClosed": "2021-10-31T22:07:31.203Z",
"elapsedTime": 1333,
"eventDate": "2018-03-08T00:04:11.233Z",
"isBreach": false,
"lossAmount": 0,
"permissions": [],
"recordNumber": "RDB000004",
"remedialCost": 0,
"reportedDate": "2018-03-08T00:07:18.373Z",
"riskRating": "Extreme",
"statusDescription": "Unknown",
"title": "Data Breach"
},
"record2": {
"id": "YXJpOmdyYzpBVTpERU1PUUFDT0dSQzpFdmVudDo0",
"dateClosed": "2021-10-31T22:07:55.737Z",
"elapsedTime": 1350,
"eventDate": "2018-02-19T03:55:37.177Z",
"isBreach": false,
"lossAmount": 0,
"permissions": [],
"recordNumber": "RDB000002",
"remedialCost": 0,
"reportedDate": "2018-02-19T03:56:08.003Z",
"riskRating": "Minor",
"statusDescription": "Unknown",
"title": "Privacy breach - statement issue"
}
}
}
To efficiently fetch data without concerns about pagination and perform bulk operations with the Dorva GRC GraphQL API, you can refer to the following article Perform bulk operations with the Drova GRC GraphQL API
This article will provide you with detailed instructions and guidance on how to use bulk query operations to streamline your data retrieval processes.