As you build observability into your workflows and processes, you need the ability to quickly retrieve, sort, and process all kinds of telemetry through APIs. With New Relic, you can gather a lot of data, but when you’re building dashboards and applications for working with your data, you want to minimize superfluous API operations.

With the NerdGraph API explorer—built on GraphQL—you can more easily query the data you need, without over-or under-fetching, and reduce manual toil in your data analysis workflows.

More specifically, in New Relic you can use NerdGraph to:

In this post, I’ll walk through two examples using NerdGraph to query information about New Relic Infrastructure cloud integrations and update their configuration values. But first a bit of history.

Using GraphQL in New Relic

Unlike typical REST APIs that often require loading from multiple endpoints, GraphQL provides a single endpoint that can manage complex queries so developers can get all the data their app needs from many services in one request.

GraphQL is strongly typed, which allows developers to explicitly declare what information is available via queries to the GraphQL service. This declaration is done via a GraphQL schema. Schemas give developers the flexibility they need to express information about the data they return. For example, each field has a description, which developers can use to indicate the proper usage of the data.

Schemas also provide the API blueprint developers need to build tools for properly constructing queries and guiding proper usage of any returned data. For example, developers can use the schema to indicate if a field has been deprecated so tools like IDEs can surface this fact and discourage use of that data.

And “schema stitching”—creating a single schema from several underlying GraphQL APIs—allows developers to deliver a unified access experience across all of their APIs, as we’ve done at New Relic:


The New Relic GraphQL implementation includes several underlying GraphQL APIs—including accounts, Infrastructure, and the New Relic database (for constructing NRQL queries).

For more information on GraphQL, the following examples of querying cloud integration configuration data use GraphQL queries and mutations:

  • Queries: GraphQL requests that only fetch data
  • Mutations: GraphQL requests that modify and fetch data

NerdGraph has a single endpoint: https://api.newrelic.com/graphiql. This launches (after authenticating the user) the NerdGraph API interface—an interactive, browser-based IDE for running GraphQL requests.

In the NerdGraph API explorer, you build and run your query on the left, and the result is returned on the right.

You can click into fields to drill into their definitions. For example, if you drill into actor, you’ll see it contains fields for user and accounts:

{

  actor {

   user {

    name

    email

    }

   accounts {

    id

    name

   }

  }

}

The fields under actor expose data from different downstream services that are unified in the GrahQL schema delivered by the GraphQL server. When you issue a query, the GraphQL server pulls apart the query and invokes a resolver for each of the services. When the queries complete (or time out or encounter errors), the GraphQL server assembles the result and returns it to you. In the example above, we get information about the user and all the accounts that they have access to.

Let’s walk through our examples to show the full power of GraphQL’s data collection capabilities.

Example 1: Querying Infrastructure cloud integrations with NerdGraph

In my first example, I’ll use NerdGraph to query for various data about the AWS integrations that are running in my New Relic account. I’ll use the data I gather in this example to update some specific settings in the next section.

Tip: If you’re planning on following along, make sure you generate an API key that you can use with New Relic’s GraphQL API. In fact, you can generate one directly from NerdGraph.

Let's start with a list of the AWS integrations I have available in New Relic Infrastructure:

AWS integrations installed in New Relic Infrastructure.
AWS integrations installed in New Relic Infrastructure.

Next, let's retrieve some information about these AWS services via a GraphQL query. I’m going to query for the cloud provider (in this case, AWS) that’s linked to my account and the set of integrations from AWS that I’ve installed. To do this, I need to pass the ID of the account I want to query—this is the account(id: MY ACCOUNT ID) part of the query.

Notice that I’m “nesting” requests to get information about the cloud provider and the integrations I’m using. If I were using a REST API, this would require multiple calls, but with the GraphQL API, I can gather this information with just one query.

 

{

  actor {

    account(id: MY ACCOUNT ID) {

      cloud {

        linkedAccounts {

          id

          externalId

          name

          authLabel

          provider {

            id

            name

            slug

          }

          integrations {

            id

            name

            service {

              id

              slug

              name

              createdAt

              updatedAt

              provider {

                name

                id

              }

            }

          }

        }

      }

    }

  }

}

When the query completes, the GraphQL server assembles the results about the AWS integrations I’ve installed, as shown below (note that I’ve truncated the example):

{

  "data": {

    "actor": {

      "account": {

        "cloud": {

          "linkedAccounts": [

            {

              "authLabel": "arn:aws:iam::8xxxxxxx7:role/NewRelicInfrastructure-Integrations-Origami",

              "externalId": "8xxxxxxx7",

              "id": 3542,

              "integrations": [

                {

                  "id": 75540,

                  "name": "RDS",

                  "service": {

                    "createdAt": 1470991744,

                    "id": 3,

                    "name": "RDS",

                    "provider": {

                      "id": 1,

                      "name": "Amazon Web Services"

                 },

                  "slug": "rds",

                  "updatedAt": 1534242454

                }

               },

                             {

                  "id": 14233,

                  "name": "S3",

                  "service": {

                    "createdAt": 1470991745,

                    "id": 4,

                    "name": "S3",

                    "provider": {

                       "id": 1,

                       "name": "Amazon Web Services"

                    },

                    "slug": "s3",

                    "updatedAt": 1534242454

                }

               },

                             {

                  "id": 12223,

                  "name": "Lambda",

                  "service": {

                    "createdAt": 1477910055,

                    "id": 14,

                    "name": "Lambda",

                    "provider": {

                      "id": 1,

                      "name": "Amazon Web Services"

                    },

                    "slug": "lambda",

                    "updatedAt": 1534242454

                  }

                 },

                              {

                  "id": 172534,

                  "name": "DynamoDB",

                  "service": {

                    "createdAt": 1470991758,

                    "id": 13,

                    "name": "DynamoDB",

                    "provider": {

                      "id": 1,

                      "name": "Amazon Web Services"

                    },

                    "slug": "dynamodb",

                    "updatedAt": 1534242454

                  }

                },



             }

           }

         ]

        }

      }

    }

  }

}

But what if I want more specific information about one of the integrations? Specifically, I want to see what tags (user-defined metadata) I’ve applied to a particular integration as well as its metrics polling interval (how often New Relic polls the integration for data), and when these settings were last updated.

To do this, I’ll need to use one of the more nuanced features of GraphQL—interfaces, an abstract type that represents a collection of common fields that other object types can implement.

So in my original query, I’ll add two new clauses:

... on CloudDynamodbIntegration{

  metricsPollingInterval

  tagKey

  tagValue

  updatedAt

}

... on CloudRedshiftIntegration{

  metricsPollingInterval

  tagKey

  tagValue

  updatedAt

}

Now, if my query hits a result that is of type CloudDynamodbIntegration or CloudReshiftIntegration, it also return the fields metricsPollingInterval, tagKey, tagValue, and updatedAt.

Here's what my (truncated) query will like now:

{

  actor {

    account(id: MY ACCOUNT ID) {

      cloud {

        linkedAccounts {

          id

          externalId

          name

          authLabel

          provider {

             ...

          }

          integrations {

             id

             name

             service {



             ...



                }

             }

             ... on CloudDynamodbIntegration{

               metricsPollingInterval

               tagKey

               tagValue

               updatedAt

             }

             ... on CloudRedshiftIntegration{

               metricsPollingInterval

               tagKey

               tagValue

               updatedAt

             }

           }

         }

       }

     }

   }

 }

In the result, notice that the DynamoDb and Redshift configuration information contain the extra fields that I specified in the query using their interfaces.

   {

               "id": 173397,

               "metricsPollingInterval": 900,

               "name": "Redshift",

               "service": {

                 "createdAt": 1497364366,

                 "id": 21,

                 "name": "Redshift",

                 "provider": {

                   "id": 1,

                   "name": "Amazon Web Services"

               },

               "slug": "redshift",

               "updatedAt": 1534242454

             },

            "tagKey": "mdw-test",

            "tagValue": null,

            "updatedAt": 1544435410

          },

          {

            "id": 112183,

            "metricsPollingInterval": 900,

            "name": "DynamoDB",

            "service": {

              "createdAt": 1470991758,

              "id": 13,

              "name": "DynamoDB",

              "provider": {

                "id": 1,

                "name": "Amazon Web Services"

              },

              "slug": "dynamodb",

              "updatedAt": 1534242454

             },

             "tagKey": "mdw-test",

             "tagValue": null,

             "updatedAt": 1549499902

           },

OK! I’ve successfully queried information about my AWS integrations in New Relic Infrastructure, and I’ve used an interface to get additional information about a specific integration. Now, I’ll use the GraphQL API to update the metrics data polling intervals in one of these integrations.

Example 2: Modifying integration configurations with NerdGraph

In GraphQL, when you modify data with a write operation, it’s called a mutation.

In this example, I’ll build a mutation to update the polling intervals of an AWS integration. First, though, I’ll set a polling interval so that we'll notice when I change it with NerdGraph.

Here are the configuration options for my AWS DynamoDB integration:


DynamoDB integration configuration options in New Relic Infrastructure.

As you can see, I’ve set the metrics data and inventory data polling intervals to every 5 minutes, and I’ve also toggled Collect tags to ON.

Now I’ll build the mutation query.

First, I'll start with the keyword mutation, and like any GraphQL API request, enclose it in a pair of curly braces,{ }.

Next, I want to specify that I’m configuring a cloud integration; so I’ll add cloudConfigureIntegration, which takes two arguments: accountId and integrations. For accountId, I’ll use the same account id from the first example to get information about the Infrastructure-linked accounts. The second argument is the integrations that I want to update. Again, integrations are specified by cloud provider, so here I want to include aws. So far my mutation looks like this:

mutation{

  cloudConfigureIntegration(

    accountId:MY ACCOUNT ID

    integrations:{aws

I want to specify that I’m updating the configuration for DynamoDB, so I’ll pass in an object with dynamodb as the key and an array that contains objects with the values I want to to set. Remember, for our mutation, we want to update the metricsPollingInterval (valid values are 300, 900, 1800, and 3600 seconds) and add a tagKey (metadata about the function of the integration).

The final part of the mutation adds a set of fields to return if my request is successful and a set of fields to return if there are any errors.

Here's the full query:

mutation{

   cloudConfigureIntegration(

     accountId:630060

     integrations:{aws:{

       dynamodb:[

         { linkedAccountId:4912

           metricsPollingInterval:1800

           tagKey:"mdw-test"

         }]

       }

    }

 )

{

   integrations{

     id

     name

     updatedAt

     ... on CloudDynamodbIntegration{

          metricsPollingInterval

          tagKey

          tagValue

          updatedAt

          }

     }

     errors{

      linkedAccountId

      message

      integrationSlug

     }

  }

}

And here’s the result, which shows no errors and indicates DynamoDB’s configuration was successfully updated:

{

   "data": {

     "cloudConfigureIntegration": {

        "errors": [],

        "integrations": [

          {

            "id": 177184,

            "metricsPollingInterval": 1800,

            "name": "DynamoDB",

            "tagKey": "mdw-test",

            "tagValue": null,

            "updatedAt": 1551139957

          }

        ]

      }

   }

}

I can now return to New Relic Infrastructure and refresh the DynamoDB configuration page:


Refreshing the DynamoDB configuration in New Relic Infrastructure.

Our mutation changed the metric polling interval from 300 seconds (5 minutes) to 1800 seconds (30 minutes), and entered tag key value of mdw-test.

That's it! I've successfully updated the configuration of a New Relic Infrastructure integration using NerdGraph.

Transfering NerdGraph data to the terminal

So, now you know how to explore the New Relic data available to you in NerdGraph, and you know how to create queries and mutations, but how do you transfer this data to your code?

To capture code-ready queries and mutations, select the Tools drop down in the NerdGraph explorer.

To copy a curl statement with the in-scope query to your clipboard, select Copy as CURL. Paste this code snippet into your terminal, or use it to populate an HTTP request in your code.

If you’re working with the New Relic CLI, select Copy as New Relic CLI from the drop down to generate a command-line ready query or mutation.

New Relic and GraphQL—easing the path for developers

As these examples show, GraphQL is extremely flexible and lightweight, and dramatically reduces the overhead of working with your New Relic data. If you want to challenge yourself even more, create some more complex queries in the Query Builder. For example, can you create a query to grab the count of all of your reporting entities? Hint: check out NerdGraph’s entity search field.

We’re passionate about making life for developers as easy as possible. Check out the resources available at developer.newrelic.com, and engage in the discussion with fellow developers on the Explorer’s Hub.