Persisted Operations

Persisted Operations refer to the concept of optimizing and securing GraphQL requests by replacing the full query string with a unique identifier. This can include the use of Persisted Operations (PO) to achieve the goal of reducing network overhead and improving performance and Automatic Persisted Query (APQ) operations solely for performance improvements.

Stellate GraphQL persisted operations allow you to save and reuse GraphQL operations on the server-side. Instead of sending the entire query/mutation every time, you can send a reference to a previously saved operation.

Generally, Persisted Operations work as follows

  • Upload a JSON file: You start Persisted Operations by uploading a JSON file either using the Stellate CLI or API. This file will contain the unique identifier for an operation.
  • Reuse Operation Identifier: In requests, clients can use the unique identifier of the saved operation instead of sending the entire operation again.

Persisted operation benefits

Using persisted operations can provide the following benefits for your GraphQL queries:

  • Cache Busting: When using Persisted Operations with a CDN, you need to handle cache busting. Stellate offers automatic and manual cache purging. Automatic purging analyzes mutations to determine cache invalidation, while manual purging generates a specialized GraphQL endpoint for purging traffic based on your schema.
  • Reduced Payload: Using Persisted Operations can reduce the payload size of GraphQL requests, especially for repeated operations. The server already knows the details of the operation based on the identifier provided by the client.
  • Infrastructure Support: Stellate enables you to adopt the infrastructure needed to sync allowed persisted operations. We do this by unfurling persisted operations in our CDN or we start supporting you, if you have already adopted persisted operations.
  • Observability: When you use Stellate persisted operations, you can also get the benefit of Stellate provided observability insights to track and analyze the performance and effectiveness of your persisted operations.

Types of persisted operations

Stellate supports two different types of persisted operations that serve as different approaches that optimize GraphQL requests by replacing the full query string with a unique identifier. There are two main types: Persisted Operations (PO) and Automatic Persisted Query (APQ) operations.

  • Persisted Operations (PO) - Persisted Operations involve registering operations on the server side. This allows the Stellate CDN to act as an operation safety bulwark. As such, Stellate Persisted Operations is a security feature as much as a performance one. Each query is assigned a unique identifier, typically a hash of the query string. When a client wants to execute a query, it sends the identifier instead of the full query string. The server then looks up the query in the Persisted Query List (PQL) and executes it. Persisted Operations provides both performance benefits and security, as only registered queries can be executed.
  • Automatic Persisted Query (APQ) - Automatic Persisted Query operations take a different approach by automatically transforming the query on the client side into a unique identifier, without explicit reliance on the ad hoc generated PQL. APQ eliminates the need for a separate registration step, simplifying the implementation process. Read https://stellate.co/docs/platform/automatic-persisted-queries to find out more about APQ.

Differences between persisted operations types

The differences between persisted operations and automated persisted query (APQ) operations include the following:

  • Registration Step: Persisted Operations require a separate registration step where queries are explicitly registered with Stellate. APQ eliminates this step by automatically transforming the query on the client side. However, APQ does this step on the client-side at runtime, and when the server responds by not knowing the query, APQ sends a second request registering the query.
  • Security: Persisted Operations provide an additional layer of security as only registered queries can be executed, while APQ relies on the client to transform the query, potentially allowing unauthorized queries from other sources.
  • Query Transformation: Persisted Operations rely on the build step/CI process to perform the transformation from query string to identifier, whereas APQ performs the transformation on the client side.

Methods for using Persisted Operations

Stellate gives you multiple methods for enabling, adjusting, and using Persisted operations:

  • Enable with the Stellate CLI - You can enable Persisted Operations by uploading a file through our CLI command. See the following sections for more information.
  • Enable using the Stellate API - You can also enable Persisted Operations by uploading a file using our API. See the following sections for more information.
  • Adjusting settings the Stellate Dashboard - While you cannot directly upload Persisted Operations in the Stellate Dashboard, you can adjust Persisted Operations settings.

The following sections describe how to use these methods for persisted operations.

Before you begin

Before you enable or disable persisted operations, you need to have:

  • A Stellate.co account and login.
  • A working Stellate Service.
  • A GraphQL client setup.
  • A client generated persisted-operations JSON file that contains all the operations used and the generated identifiers. The query needs to add __typename to the selection-sets for Stellate to be aware of the types they are querying. The Relay client, GraphQL Code generator, and the Rover apollo-cli support this feature and have configurations for types. Note that the links are informational and do not represent an endorsement of these tools.

Upload Persisted Operations with the CLI

To upload Persisted Operations in Stellate, you can run the following CLI command:

Persisted Operations CLI command:

stellate persisted-operations push ./po.json

The po.json file is a mapping of hash --> query

Enable Persisted Operations with the Stellate API

You can use the Stellate Public API to programmatically enable Persisted Operations. The API provides endpoints to manage the configuration settings for APQ and other related features. By making appropriate API calls, you can enable or disable Persisted Operations as needed.

Note: To use the public API, you must create a user token first. Head to your Access Tokens page, click the Create a token button, and name the new token. Make sure also to copy the token to a safe place; you won't be able to see it again.

To use the Stellate Public API for Persisted Operations:

  1. Navigate to Stellate Docs > Public API > https://graph.stellate.co/ .
  2. Click the Show Documentation Explorer at the top of the Left Navigation Bar.
  3. Find the following APIs or simply click on them.

The Persisted Operation APIs contain the Implements and Fields information for the selected API call.

Invoking Persisted Operations on a mutation example

You can use our public API to upload persisted operations. The following example shows the use of a mutation that is designed to upload persisted operations with a given service ID and an array of persisted operations.

mutation UploadPersistedOperations($serviceId: ID!, $persistedOperations: [PersistedOperationsInput!]!) {
	uploadPersistedOperations(serviceId: $serviceId, persistedOperations: $persistedOperations) {
		id
	}
}

Variables for the mutation example

The following example shows how you can upload Persisted Operations with variables. The example pairs with the prior mutation example. In this example, the variable $limit is a variable of type Int and is used in the pokemons query to limit the number of results returned. You need to set the variable with a specific value when executing the query.

{
	"serviceId": "your-service-id",
	"persistedOperations": [
		{
			"hash": "some-hash",
			"query": "query($limit: Int!) { pokemons(limit: $limit) { id name __typename } }"
		}
	]
}

Configure Persisted Operations in the Dashboard

You can configure Persisted Operations in the Stellate Dashboard. These settings can be adjusted based on your specific requirements.

To use Persisted Operations in the Stellate Dashboard, login to your Stellate account. Once you login, click the button in the upper left that lists your organization name and perform the following steps:

  1. Navigate to your Stellate Services and click on the Service that you want to work with. ****
  2. For your Service, click on the Security tab, between the Requests and Schema tabs.
  3. In the Persisted Operations view, review all of your operations by
    1. The operation name of the query.
    2. The hash, when you created it.
    3. When we've last seen it in our metrics.
  4. Next, click on the Config tab to open the Config Editor.
  5. In the Config Editor, enter the persistedOperations:{ key to see a menu of persisted operations. These are:
    1. apq: This operation is set totrue by default. You can set it to true or false to enable or disable automatic persisted queries (APQ). The APQ operation allows you to toggle our existing automatic persisted queries option off or on.
    2. rejectInvalidHashes: This operation is set to false by default. If the operation is set to true, it rejects anything that is not a query hash, such as a stringified query user. As such it allows any normal query or query hash to be sent. Keeping the default as false can incur security risks. Setting this operation to true provides an extra layer of security for your queries.
    3. SendHashToOrigin: This operation is set to false by default. Set this operation to true, when the origin knows about persisted operations, to have Stellate send the hash to the origin server from our CDN. In this case, we translate the persisted operation inside the CDN, send the query string onto the origin server, and then your origin needs to unfurl the hash to the query string. Set this operation to false, when the origin doesn’t know about the persisted operations. When set to fale, we send the query-string as you will already have an unfurled hash because Stellate did it in the CDN.

Discover more