persisted_documents
The persisted_documents configuration allows you to enable [Persisted Documents] on Hive Router
that allows you to reduce the payload size of your GraphQL requests and secure your GraphQL API by
allowing only operations that are known and trusted by your Router.
Learn more about Persisted Documents with Hive Console
Configuration Structure
The persisted_documents key is a top-level object in your router.config.yaml. It contains the
following fields:
First you need to enable persisted documents by setting the enabled field to true.
persisted_documents:
enabled: trueSource Configuration with source
The source field defines where the Router will load the persisted documents from. It supports two
sources: Hive Console CDN and a local file.
source: (object) The source configuration for persisted documents.
Hive Console CDN
Then we need a way to fetch the persisted documents. The recommended way is to use Hive Console as your persisted documents storage.
hive: (object) The Hive Console CDN source configuration.endpoint: (string) The Hive Console CDN endpoint to fetch persisted documents from. Alternatively you can set theHIVE_CDN_ENDPOINTenvironment variable.key: (string) The Hive Console CDN API key to authenticate requests. Alternatively you can set theHIVE_CDN_KEYenvironment variable.
To do so, you can either use environment variables or directly set the endpoint and key fields.
persisted_documents:
enabled: true
source:
hive:
endpoint: https://cdn.graphql-hive.com/artifacts/v1/... # Use your Hive CDN endpoint here
key: hvABCD # Use your Hive CDN API key hereor using environment variables:
persisted_documents:
enabled: trueThen set the following environment variables in your environment:
export HIVE_CDN_ENDPOINT="https://cdn.graphql-hive.com/artifacts/v1/..."
export HIVE_CDN_KEY="hvABCD"A Persisted Documents File as Source
Alternatively, you can also load persisted documents from a local file.
file: (string) The path to the local persisted documents JSON file.
persisted_documents:
enabled: true
source:
file: ./persisted_documents.json # point to your local persisted documents fileThat file must be a JSON file containing a map of document IDs to GraphQL operations, for example:
{
"a1b2c3d4e5": "query GetUser($id: ID!) { user(id: $id) { id name } }",
"f6g7h8i9j0": "mutation UpdateUser($id: ID!, $name: String!) { updateUser(id: $id, name: $name) { id name } }"
}Configure Extraction of Document ID from Requests with spec
The spec field defines how the Router will extract the persisted document ID from incoming
requests. By default it is set to hive which expects the document ID to be provided in the body as
documentId.
spec: (object) The specification for extracting document IDs from requests.- Possible values are:
hive: The default Hive specification usingdocumentIdin the request body.apollo: The Apollo Persisted Documents specification usingextensions.persistedQuery.sha256Hashin the request body.relay: The Relay specification usingdoc_idin the request body.expression: A custom specification using a user-defined expression.
documentId in Request Body (Hive / Default)
The default hive spec expects the persisted document ID to be provided in the request body as
documentId.
So the request body should look like this:
{
"documentId": "my-app~my-version~a1b2c3d4e5",
"variables": {
"id": "123"
}
}Then the Router will look up the operation associated with the provided documentId and execute it.
Apollo Persisted Documents Spec using extensions.persistedQuery.sha256Hash
There is also support for the Apollo Persisted Documents spec, which expects the document ID to be
provided in the extensions.persistedQuery.sha256Hash field of the request body.
To use this spec, set the spec field to apollo:
persisted_documents:
enabled: true
spec: apolloSo the request body should look like this:
{
"extensions": {
"persistedQuery": {
"version": 1,
"sha256Hash": "ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"
}
}
}which can be sent like this using curl:
curl -X POST -H 'Content-Type: application/json' http://localhost:4000/graphql \
-d '{"extensions":{"per sistedQuery":{"version":1,"sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"}}}'Then the Router will look up the operation associated with the provided sha256Hash and execute it.
Relay Specification using doc_id in Request Body
You can also use the Relay specification, which expects the persisted document ID to be provided in
the request body as doc_id.
To use this spec, set the spec field to relay:
persisted_documents:
enabled: true
spec: relayThen the request body should look like this:
{
"doc_id": "a1b2c3d4e5",
"variables": {
"id": "123"
}
}Then the Router will look up the operation associated with the provided doc_id and execute it.
Custom Specification with expression
If none of the built-in specifications fit your needs, you can define a custom specification using
the expression option.
expression: (string) A VRL expression that extracts the document ID from the incoming request.
To use a custom specification, set the spec field to expression and provide the expression
field:
persisted_documents:
enabled: true
spec:
expression: .request.body.customDocumentIdUsing Header to Provide Document ID
In this example, we extract the document ID from a custom header x-document-id.
persisted_documents:
enabled: true
spec:
expression: .request.headers."x-document-id"Then the request should include the x-document-id header:
curl -X POST -H 'Content-Type: application/json' -H 'x-document-id: a1b2c3d4e5' http://localhost:4000/graphql \
-d '{"variables":{"id":"123"}}'Using a Query Parameter to Provide Document ID
In this example, we extract the document ID from a query parameter query_id.
persisted_documents:
enabled: true
spec:
expression: .request.body.query_idThen the request URL should include the query_id query parameter:
curl -X POST -H 'Content-Type: application/json' 'http://localhost:4000/graphql?query_id=a1b2c3d4e5' \
-d '{"variables":{"id":"123"}}'Allowing Non-Persisted Arbitrary Documents with allow_arbitrary_operations
After enabling persisted documents, by default the Router will reject any requests that do not provide a valid persisted document ID.
allow_arbitrary_operations: (boolean / object) Whether to allow arbitrary operations alongside persisted documents. Default isfalse.
If you want to allow arbitrary operations alongside persisted documents, you can set the
allow_arbitrary_operations field to true.
persisted_documents:
enabled: true
allow_arbitrary_operations: trueConditional Allowance with expression
Alternatively, you can conditionally allow arbitrary operations based on a user-defined expression.
expression: (string) A VRL expression that evaluates to a boolean value to determine whether to allow arbitrary operations.
To use a conditional allowance, set the allow_arbitrary_operations field to an object with the
expression field:
persisted_documents:
enabled: true
allow_arbitrary_operations:
expression: .request.headers."x-allow-arbitrary" == "true"Then the Router will evaluate the provided expression for each request. If it evaluates to true,
the Router will allow arbitrary operations; otherwise, it will enforce persisted documents only.
In the example above, you can allow arbitrary operations by including the x-allow-arbitrary: true
header in your request:
curl -X POST -H 'Content-Type: application/json' -H 'x-allow-arbitrary: true' http://localhost:4000/graphql \
-d '{"query":"query { user(id: \"123\") { id name } }"}'