Generate JSON files for Persisted Operations

You have several options for generating your Persisted Operations JSON files to upload to Stellate. These include the following:

  • Generate your JSON file with the Relay compiler
  • Generate your JSON file with the @apollo/persisted-query-lists package
  • Generate your JSON file with GraphQL Code Generator

These tools work for any type of OS and place the generated JSON file at the workspace-root where you run the command.

For your convenience, the following topics summarize how to use these tools to generate a JSON file. For details, we recommend that you read the source documentation in detail.

Generate your JSON file with Relay

Relay is a convenient tool maintained by the Meta (formerly Facebook) product infrastructure engineering teams. To use it follow the Relay installation instructions.

Once Relay is installed, to start generating persisted-operations with the relay-compiler, do the following steps:

  1. Per the Relay instructions, edit the package.json file. Specify the persistConfig option in the Relay configuration section:

    "persistConfig": {
        "file": "./persisted_queries.json"
    }
    

    Read Local Persisted Queries in the Relay documentation for more details.

  2. Send the generated persisted_queries.json file to the Stellate server using the following CLI command:

  stellate persisted-operations push ./persisted_queries.json

Network Layer Fetch

When using the network layer fetch implementation to pass an ID parameter in the POST body (such as doc_id) instead of a query parameter, note the following:

  1. Define the following, instead of using body.doc_id.
    body: JSON.stringify({
      extensions: {
        persistedQuery: {
          version: 1,
          sha256Hash: operation.id
        }
      },
      variables,
    }),

Generate your JSON file with Apollo

You can use @apollo/persisted-query-lists package to generate your .json file for persisted queries. Read the Apollo documentation on Apollo Rover and Automatic persisted queries.

To use Rover, you need to follow the Apollo installation instructions. They are summarized as follows:

  1. Install @apollo/generate-persisted-query-manifest.
  2. Run npx generate-persisted-query-manifest to generate your persisted-operations file.
  3. Install A persisted queries the @apollo/persisted-query-lists package. This package contains helpers that work with the persisted queries link.

Edit your Config file to send __typename

For stellate and your GraphQL client (for example apollo-client) to understand the operations that are flowing through the CDN we need to have the __typename included in your documents. We can achieve this by adding that selection to every document through the configuration.

  1. Edit your apollo-persisted-query-lists configuration file. The file is called persisted-query-manifest.config.ts
  2. In the configuration file, include __typename for every selection

The following snippet illustrates the use of __typename in the configuration file.

import { PersistedQueryManifestConfig, defaults } from "@apollo/generate-persisted-query-manifest";
import { SelectionNode, DefinitionNode, DocumentNode, Kind, parse, print } from 'graphql'

const formatNode = <
  T extends SelectionNode | DefinitionNode | DocumentNode,
>(
  node: T
) => {
  if ('definitions' in node) {
    const definitions: DefinitionNode[] = [];
    for (const definition of node.definitions) {
      const newDefinition = formatNode(definition);
      definitions.push(newDefinition);
    }

    return { ...node, definitions };
  }

  if ('selectionSet' in node) {
    const selections: SelectionNode[] = [];
    let hasTypename = node.kind === Kind.OPERATION_DEFINITION;
    if (node.selectionSet) {
      for (const selection of node.selectionSet.selections || []) {
        hasTypename =
          hasTypename ||
          (selection.kind === Kind.FIELD &&
            selection.name.value === '__typename' &&
            !selection.alias);
        const newSelection = formatNode(selection);
        selections.push(newSelection);
      }

      if (!hasTypename) {
        selections.push({
          kind: Kind.FIELD,
          name: {
            kind: Kind.NAME,
            value: '__typename',
          }
        };
      }

      return {
        ...node,
        selectionSet: { ...node.selectionSet, selections },
      };
    }
  }

  return node;
};

const config: PersistedQueryManifestConfig = {
  createOperationId(query) {
    const newNode = formatNode(parse(query));
    return defaults.createOperationId(print(newNode))
  }
};

export default config;

The prior code snippet is provided to supplement the Apollo documentation, as it currently does not address this topic in full.

Generate a JSON File with GraphQL Code Generator

You can also use ****GraphQL Code Generator to generate your .json file for persisted queries.

For information about using addTypenames for GraphQL Codegen, read the following topics:

Send Persisted Operations with URQL

URQL is a GraphQL client that can use one of the generated JSON files to send persisted-operations at runtime to Stellate and/or your origin server. Read the URQL documentation for more details about using this client.