Skip to main content

Prismatic API Queries and Mutations

GraphQL queries

When fetching data from Prismatic's GraphQL-based API, you issue a query. Within the query, you can declare which properties you want to fetch. It's similar to an SQL SELECT statement.

For example, this query will allow you to fetch all integrations, including their ID, name and description:

query myExampleIntegrationQuery {
integrations {
nodes {
id
name
description
}
}
}

Note that the array of integrations you receive are nested in a property called nodes. In GraphQL nomenclature, a "node" is a single record of a certain type (in this case, a node represents a single integration).

The response you get back from the API will look like this:

{
"data": {
"integrations": {
"nodes": [
{
"id": "SW50ZWdyYXRpb246M2ZhMzcwMDEtMWUzOS00Mjg3LTkyNDEtOTRkZjRjNTcyNmMy",
"name": "Salesforce",
"description": "Sync contact information from Acme to your Salesforce account"
},
{
"id": "SW50ZWdyYXRpb246ZjRhMTAxMmYtYWJjZS00NDI3LTljMTctMDZkMzI1YTIxOThk",
"name": "HubSpot",
"description": "Sync contact information from Acme to your HubSpot account"
}
]
}
}
}

Nested GraphQL queries

A huge benefit of GraphQL is that you can fetch all of the information you need in a single request, and you can avoid the "N+1 problem". Nesting record types in a query is similar to a JOIN clause in SQL - you can fetch records of multiple types that are associated with one another.

For example, suppose you want a list of all of your customers, the instances they have deployed to them, and some information about the integration that each instance is created from. You can fetch all of that data by nesting integration as a property of an instance node, and by nesting instances as a property of a customer node, like this:

query myExampleCustomersInstances {
customers {
nodes {
id
name
instances {
nodes {
id
name
integration {
id
versionNumber
}
}
}
}
}
}

The result is a nested JSON response that mimics the form of your request:

{
"data": {
"customers": {
"nodes": [
{
"id": "Q3VzdG9tZXI6ODk4Y2Q1OTYtNzI5MS00NmQxLWE2YWMtZTA1YTNkZTEwZDJj",
"name": "Hooli",
"instances": {
"nodes": [
{
"id": "SW5zdGFuY2U6YzczZmE5YzQtYzFiYS00ZWQ5LWIwNzktM2FkNzYxODFmZWY5",
"name": "Salesforce",
"integration": {
"id": "SW50ZWdyYXRpb246OWNjODA0NjYtNzczMC00NzMyLThhNjUtMDQ2MzgwZjcxNGJh",
"versionNumber": 2
}
},
{
"id": "SW5zdGFuY2U6YTUyYTJiZjEtZTljYS00ZmI4LTg0NzAtYmEzNmI2MGUxZjE5",
"name": "Microsoft Outlook",
"integration": {
"id": "SW50ZWdyYXRpb246OTRlNjU3YmItY2VhMy00ZmIxLWIzYjMtYTE3MzdjMjI5MDM1",
"versionNumber": 1
}
}
]
}
},
{
"id": "Q3VzdG9tZXI6YmZmYzdiYmItMzY2Ny00YWQyLWI2M2YtNjQ5YzkzNzFlNGJj",
"name": "Pied Piper",
"instances": {
"nodes": []
}
}
]
}
}
}

GraphQL query filters

A filter is similar to a WHERE clause in SQL - it allows you to only fetch a subset of records. Filters are passed as parameters to a query.

For example, we can query for all integrations whose name contains (case-insensitive) the word "Salesforce":

query myExampleSFDCIntegrations {
integrations(name_Icontains: "Salesforce") {
nodes {
id
name
}
}
}

Each query has a unique set of filters that can be applied - some filters relate to the name of the record, others to the timestamp when it was created, etc.

GraphQL mutations

A mutation allows you to manipulate (create, update or delete) data. You can set properties for a record by passing a mutation's input parameter a set of values.

For example, this mutation creates a new customer with a name and external ID:

mutation {
createCustomer(input: { name: "Pied Piper", externalId: "fleventy-five" }) {
customer {
id
name
}
errors {
field
messages
}
}
}

A mutation will return the object that was mutated:

{
"data": {
"createCustomer": {
"customer": {
"id": "Q3VzdG9tZXI6OTUxNjllZGUtMDM3OC00N2Y3LTg1Y2MtNDBhODZiN2JiYjI2",
"name": "Pied Piper"
},
"errors": []
}
}
}

Each mutation takes a different set of inputs. Luckily, GraphQL is self-documenting. Open the GraphQL Explorer to see the parameters that each mutation expects.

Mutation error messages

If your mutation encounters an error (for example, if you try to create a new customer with a name or external ID that is already taken by an existing customer), your mutation will return null for the mutated record, and the errors array will be populated with error messages:

{
"data": {
"createCustomer": {
"customer": null,
"errors": [
{
"field": "name",
"messages": ["A customer with the specified name already exists."]
},
{
"field": "external_id",
"messages": ["A Customer with that External ID already exists."]
}
]
}
}
}
Mutations with errors still return an HTTP 200

Note that responses to GraphQL requests that are properly authenticated and formatted always return an HTTP 200, even if an error occurred. To catch errors, make sure that you examine the errors array. If the length of the array is greater than zero, the mutation failed for some reason.

GraphQL parameters

It's a good idea to parameterize queries and mutations (rather than generating queries or mutations through string concatenation). Parameterization allows you to send a standard query or mutation in your request, accompanied by a JSON object representing those parameters' values.

Parameters are specified in the query or mutation's declaration, along with their types. Parameters are prepended with a $ character, and can be referenced throughout the query or mutation.

For example, $customerId and $customerName here are declared as an ID! and String respectively and are used in an updateCustomer mutation:

mutation updateCustomerName($customerId: ID!, $customerName: String) {
updateCustomer(input: { id: $customerId, name: $customerName }) {
customer {
id
name
}
errors {
field
messages
}
}
}

Along with this mutation, we can send a parameter payload like

{
"customerId": "Q3VzdG9tZXI6OTUxNjllZGUtMDM3OC00N2Y3LTg1Y2MtNDBhODZiN2JiYjI2",
"customerName": "Hooli"
}

Multiple queries or mutations in single request

Multiple queries or mutations can be issued in a single request. If you issue the same query or mutation twice in one request, you must alias your queries.

For example, you can issue two createCustomer mutations in one request, and alias the requests c1 and c2 respectively like this:

mutation createTwoCustomers {
c1: createCustomer(input: { name: "First Customer" }) {
customer {
id
}
errors {
field
messages
}
}
c2: createCustomer(input: { name: "Second Customer" }) {
customer {
id
}
errors {
field
messages
}
}
}

The response you receive will match your aliases:

{
"data": {
"c1": {
"customer": {
"id": "Q3VzdG9tZXI6NzgwZGIyNjItZWM0OS00NjljLTk2NmEtMjg5YTBiZmQ0M2Mw"
},
"errors": []
},
"c2": {
"customer": {
"id": "Q3VzdG9tZXI6NzA1NzFiNDctZGUzZi00ZDk4LWEyYjItMDM2ZjBiMDRlODcw"
},
"errors": []
}
}
}