Generate JSON files for Persisted Operations
You have several options for generating your Persisted Operations JSON files to upload to Stellate. 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.
Using Relay
Relay is a convenient tool maintained by the Meta (formerly Facebook) product infrastructure engineering teams. To use it follow the Relay installation instructions.
Instructions for Persisted Queries with Relay
Read about Relay , Installing Relay , and the Relay guide to persisted queries .
Once Relay is installed, to start generating persisted-operations with the relay-compiler, do the following steps:
-
Per the Relay instructions, edit the
package.json
file. Specify thepersistConfig
option in the Relay configuration section:"persistConfig": { "file": "./persisted_queries.json" }
Read Local Persisted Queries in the Relay documentation for more details.
-
Send the generated
persisted_queries.json
file to the Stellate server using the following CLI command:
stellate persisted-operations push ./persisted_queries.json
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:
Stellate does not support body.doc_id
, when sending persisted operations.
You may have read instructions in the Relay Network Layer
Changes
to send body.doc_id
. However, note that the spec to support this has no
defined way for altering the base document body; it only supports query variables
, extensions
and operationName
, where extensions are meant for
these changes. In theory query is not allowed to be null but we implicitly
agree to this contract in context of Persisted Operations.
Define the following, instead of using body.doc_id
.
body: JSON.stringify({
extensions: {
persistedQuery: {
version: 1,
sha256Hash: operation.id
}
},
variables,
}),
Using 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:
- Install
@apollo/generate-persisted-query-manifest
. - Run
npx generate-persisted-query-manifest
to generate your persisted-operations file. - 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
You can use the following step if you intend to not send the hashes on to the origin server.
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.
- Edit your apollo-persisted-query-lists configuration file. The file is called
persisted-query-manifest.config.ts
- 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.
Using GraphQL Code Generator
You can also use GraphQL Code Generator to generate your .json
file for persisted queries.
Read the GraphQL Code Generator documentation for the details on using GraphQL Code Generator to create your .json file for persisted operations.
For information about using addTypenames
for GraphQL Codegen, read the following topics:
- Normalize Caches - This topic provides a high
- Persisted Documents - This topic includes the helper to add
__typename
- Installation and Setup - Read this topic, if you plan to send the persisted-operations to their origin.
Using 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.