Why is Hoxhunt using GraphQL
We chose GraphQL as our API layer as it gives significant flexibility to our developers and to our partners. It enables user of the API to query a strongly typed API and get exactly the data and only the data is required for the task at hand.
About GraphQL
The GraphQL data query language is:
-
A specification. The spec determines the validity of the schema on the API server. The schema determines the validity of client calls.
-
Strongly typed. The schema defines an API's type system and all object relationships.
-
Introspective. A client can query the schema for details about the schema.
-
Hierarchical. The shape of a GraphQL call mirrors the shape of the JSON data it returns. Nested fields let you query for and receive only the data you specify in a single round trip.
-
An application layer. GraphQL is not a storage model or a database query language. The graph refers to graph structures defined in the schema, where nodes define objects and edges define relationships between objects. The API traverses and returns application data based on the schema definitions, independent of how the data is stored.
How do I use Hoxhunt GraphQL API?
First you need to acquire Auth token from your user settings page. This is referred as AUTH_TOKEN in examples below. After you’ve got your auth token, you can start querying the API. Let's do a simple example with Python and Curl on command-line.
Python
# An example to get the current user information using Hoxhunt API
import requests
headers = {"Authorization": "Authtoken AUTH_TOKEN"}
# A simple function to use requests.post to make the API call.
# Note the json= section.
def run_query(query, variables={}):
request = requests.post(
'https://api.hoxhunt.com/graphql-external',
json={'query': query,
'variables': variables},
headers=headers)
if request.status_code == 200:
return request.json()
else:
raise Exception(
"Query failed to run by returning code of {}. {}"
.format(request.status_code, query))
# The GraphQL query defined as a multi-line string.
query = """
{
currentUser {
emails {
address
}
}
}
"""
result = run_query(query) # Execute the query
print(result)
# {'data': {'currentUser': {'emails': [{'address':
# '[email protected]'}]}}}
Curl
curl https://api.hoxhunt.com/graphql-external \
-X POST \
-H "Authorization: Authtoken AUTH_TOKEN" \
-H "Content-Type: application/json" \
--data-binary \
'{"query":"{\n currentUser {\n emails {\n address\n }\n }\n}\n","variables":null,"operationName":null}'
Example queries
Below we have example queries that might get you started building your integration. Use your preferred client to execute the actual queries.
Find incidents that were matched by an incident rule
- We query the first 3 matches
- We filter by the incident rule name "User acted on threat"
query FindEscalatedUserActedIncidents {
currentUser {
organization {
incidentRules(filter: { name_eq: "User acted on threat" }) {
incidentMatches(first: 3) {
timestamp
incident {
_id
lastReportedAt
threatCount
}
}
}
}
}
}
Adding a note to an existing incident
- We filter by the incident id
- We provide text content for the note
mutation CreateIncidentNote {
addIncidentNote(
incidentId: "64998614423a1e9d5747fce0"
note: {
text: "This incident has been resolved and relevant parties have been notified."
}
) {
notes {
_id
text
}
}
}
Filtering, sorting and paginating lists of data
For lists of data, we provide pagination alongside with sorting and filtering by their primitive values.
Pagination
Pagination should always be used when fetching large amounts of data, this quarantees that the API call will not timeout and returns a successful response.
- first, last and skip parameters can be used to utilize the built in pagination for lists.
Get the first 100 incidents:
query {
incidents(first: 100, skip: 0) {
_id
createdAt
state
}
}
Then we can fetch the next 100 incidents from there on:
query {
incidents(first: 100, skip: 100) {
_id
createdAt
state
}
}
Sorting
Sort by creation date of the object:
query {
incidents(sort: createdAt_DESC, first: 10) {
_id
createdAt
state
}
}
Filtering
Filtering by one value:
query {
incidents(filter: { humanReadableId_eq: "hox-large-crane-329a" }) {
_id
createdAt
state
}
}
Filtering by multiple values:
query {
incidents(
filter: { AND: [{ state_eq: OPEN, threatCount_gte: 100 }] }
first: 100
) {
_id
createdAt
state
}
}
Filtering by searching with "or" conditioning:
query {
incidents(
filter: { OR: [{ state_eq: OPEN, threatCount_gte: 100 }] }
first: 100
) {
_id
createdAt
state
}
}