Introduction
Starting in v3.0.0, Ghostwriter includes a GraphQL API powered by the Hasura GraphQL Engine. You can use the API to perform all the same tasks available via the web interface. It’s a powerful tool for automation, pushing and pulling data, and integrating external tools with Ghostwriter.Interacting with the API
With the default configuration, the GraphQL endpoints are:- Local: http://127.0.0.1:8080/v1/graphql
- Production: https://<HOST>/v1/graphql
Content-Type: application/json
in the headers and a body like this:
SampleQuery.json
query
and operationName
keys are required. The operationName
tells GraphQL which action should be executed. This can be helpful if you stack multiple queries and mutations in the query
key and want to execute them selectively (see the example at the bottom of the page).
The response will always come back in this form:
SampleResponse.json
Some basic GraphQL knowledge, such as the difference between a query and a mutation, will make the following sections easier to understand. You will also be better prepared to write your custom queries.
Basic Queries
A basic query looks like this:SampleClientQuery.json
id
field of all client records accessible to the requesting user.
The query can be modified to return additional data, like the codename
and note
fields:
SampleClientQuery.json
Field names are often placed on separate lines in GraphQL examples and the Hasura Console, but this is not required. You can separate field names with spaces, too. This option is easier to use when preparing queries for web requests because it removes the need to convert newlines to
\n
.SampleClientQuery.json
id
and title
of every finding in the database to get all our data back in a single request:
SampleClientQuery.json
title
contains SMB
. This can be accomplished with nested database relationships and the addition of a condition:
SampleClientQueryWithFilter.json
Note how the above example references the
severity
relationship, instead of returning the findings severityId
field. The severityId
is just the foreign key, an integer. The query uses the relationship to return the string value set to represent that severity (e.g., High).Interacting via Automation
Queries are simple until you need to pack them into the nested JSON for a web request. It would be best if you used a script to craft the proper payloads and make them repeatable. You can write your query in a human-readable format and then use something like JavaScript’sJSON.stringify()
or Python’s json.dumps()
to create the properly formatted payload for the POST request. However, this can lead to accidental double-encoding which will cause issues down the line. The simplest option is using a library built for handling GraphQL requests, like gql
for Python.
Here is an example query request in Python using the gql
library. For more examples and ideas, see this section:
SampleAPI.py