Relic Solution: Reading and writing NerdStorage via NerdGraph

Introduction

Per our documentation, NerdStorage is defined as the following:

NerdStorage is used to store and retrieve simple sets of data, including users’ configuration settings and preferences (like favorites), or any other small data sets. This storage is unique per Nerdpack, and can’t be shared with any other Nerdpack.

NerdStorage can be classified into three categories:

  • User storage : Data that is attached to a particular user. If you’re authenticated as the user the data is attached to, you can read it and write it.
  • Account storage : Data that is attached to a particular account. If you’re authenticated and can access the account, you can read and write to account scoped NerdStorage. Visibility of account data is also determined by master/subaccount rules: If a user has access to the master account, then they also have access to data in all subaccounts.
  • Entity storage : Data that is attached to a particular entity. If you can see the corresponding entity, you can read and write data on that entity.

Most commonly, NerdStorage documents are written and retrieved directly via our SDK, or through the newrelic command line tool. However, you might have a need to reach NerdStorage documents programmatically, and I’m happy to report this is possible!

Simply put — if you’re using CURL, you can read/write NerdStorage documents and collections by following these three steps:

  1. Build your query or mutation in the NerdGraph API explorer
  2. Select “Copy as CURL” from the Tools menu
  3. Add the header NewRelic-Package-Id: {Nerdpack UUID} to the resultant API call

That’s really all there is! However, if you’d like to dig further into the why, please continue along.

Basic concepts

As mentioned, a single Nerdpack’s NerdStorage exists in three scopes — those scopes being ACTOR (user), ACCOUNT, and ENTITY.

NerdGraph is a GraphQL service, and as such, NerdStorage documents and collections can either be queried or mutated.

Queries

I would highly recommend building your queries in our API explorer to make things simple, but depending on the scope, you will need to be querying a very specific nerdStorage subfield.

On a per-scope basis, here’s where those subfields are located:

Actor

{
  actor {
    nerdStorage
    ...
  }
}

Account

{
  actor {
    account(id: accountIdHere) {
      nerdStorage
      ...
    }
  }
}

Entity

{
  actor {
    entity(guid: "entityGuidHere") {
      nerdStorage
      ...
    }
  }
}

Mutations

Similarly, I’d recommend building your mutations graphically, but here’s a tip to help you along.

The scope is defined by the field scope.name (this will be ACTOR, ACCOUNT, or ENTITY), and the ID of that object is then defined by scope.id.

In terms of what the ID represents, here’s how it breaks down:

  • For ACTOR, scope.id is your user ID.
  • For ACCOUNT, scope.id represents the account ID.
  • For ENTITY, scope.id is your entity’s GUID.

As an example, here’s how I would write an entity-scoped document:

mutation {
  nerdStorageWriteDocument(collection: "test-collection", document: {key: value}, documentId: "test-document", scope: {id: "entityGuidHere", name: ENTITY})
}

Executing the calls

Although you can build out a query or mutation in the API explorer, you cannot execute the subsequent NerdStorage API call in this interface.

As mentioned, NerdStorage exists in the context of a single Nerdpack at a time, and that context is defined by the HTTP header NewRelic-Package-Id. This header must be supplied if you are reading or writing NerdStorage via NerdGraph.

Due to this requirement, an HTTP call to NerdStorage brings us back to the three steps at the beginning of this post:

  1. Build your query or mutation in the NerdGraph API explorer
  2. Select “Copy as CURL” from the Tools menu
  3. Add the header NewRelic-Package-Id: {Nerdpack UUID} to the resultant API call

Following that, an example mutation would look like this:

curl https://api.newrelic.com/graphql \
  -H 'Content-Type: application/json' \
  -H 'API-Key: apiKeyHere' \
  -H 'NewRelic-Package-Id: nerdpackUuidHere' \
  --data-binary '{"query":"mutation {\n  nerdStorageWriteDocument(collection: \"test-collection\", document: {key: value}, documentId: \"test-document\", scope: {id: \"entityGuidHere\", name: ENTITY})\n}\n", "variables":""}'

…and if I wanted to read the document that I just wrote, I’d execute the following:

curl https://api.newrelic.com/graphql \
  -H 'Content-Type: application/json' \
  -H 'API-Key: apiKeyHere' \
  -H 'NewRelic-Package-Id: nerdpackUuidHere' \
  --data-binary '{"query":"{\n  actor {\n    entity(guid: \"entityGuidHere\") {\n      nerdStorage {\n        document(collection: \"test-collection\", documentId: \"test-document\")\n      }\n    }\n  }\n}\n", "variables":""}'

That’s all there is to it. Have a good one.

1 Like