You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This RFC is intended to add (Automatic) Persisted Operations to the spec. A persisted operation contains
3
+
This RFC is intended to add Persisted Operations to the spec. A persisted operation contains
4
4
a _hash_ of the `operation` that we are sending to the server, the server can translate this to the proper
5
5
`operation` and execute it.
6
6
@@ -11,16 +11,11 @@ With Persisted Operations we have a few goals:
11
11
- Lock down the number of request permutations (the server can choose to only accept persisted operations it is aware of)
12
12
13
13
## Flow
14
-
15
14
### Producing the document-id
16
15
17
-
To produce a deterministic `documentId` we need a standardised way of stringifying to a minimal relevant document.
18
-
In doing so we also avoid producing different ids for documents that contain a possible extra redundant character.
19
-
20
-
We need to produce a minimal GraphQL Document according to the spec, [stripping all ignored tokens](https://spec.graphql.org/October2021/#sec-Language.Source-Text.Ignored-Tokens).
21
-
The only non-excessive ignored token is a single space character (U+0020) that must be inserted between two non-punctuator tokens.
22
-
23
-
After stringifying we can produce a SHA-256 hash of the stringified document which we can save somewhere and use as an identifier for our GraphQL server.
16
+
To produce a `documentId` we'll take a document containing the operation, including its fragments and perform a hashing algorithm like
17
+
SHA-256 on the document. Now the the correlation of a document and its hash can be persisted to a GraphQL Server and the client can
18
+
send this hash in GraphQL Requests.
24
19
25
20
### Sending
26
21
@@ -36,28 +31,12 @@ By definition `query` contains cacheable data so we can send this either as a `G
36
31
37
32
When sending GraphQL variables along with a `query` operation over the `GET` HTTP method, the URL size limit (typically 2048
38
33
characters) should be considered if the URL's query string is to be employed to encode these GraphQL variables. If this is an
39
-
issue, one should consider utilizing a `POST` request's `body` or an HTTP header to encode these variables.
34
+
issue, one should consider utilizing a `POST` request's `body` or an HTTP header to encode these variables. When using a HTTP header
35
+
to encode the variables the server has to add this request-header to the `Vary` header to ensure the correct cache-key is achieved.
40
36
41
37
### Executing
42
38
43
39
When a server receives a request containing only `documentId` it is assumed that the server can perform this lookup, when the lookup
44
40
fails the server responds with a status code 400 or 404 and denies the request. When the persisted operation can be found the server
45
41
can assume that it's dealing with a valid GraphQL document, however, the schema could have changed so the server _should_ still validate
46
42
before executing.
47
-
48
-
## Automatic persisted operations
49
-
50
-
We can expand persisted operations with an "Automatic" mode which was initially pioneered by [Apollo](https://www.apollographql.com/docs/apollo-server/performance/apq/)
51
-
with the automatic mode we have no expectation of the server being aware of our `documentId` before sending it. This means we
52
-
can "teach" the server about the documents we are sending on the fly.
53
-
54
-
For hashing and sending the persisted operation we keep the aforementioned flow, however, the flow after is altered as the server
55
-
responds with a status code 200 and a GraphQLError containing a message of `PersistedOperationNotFound` when it supports persisted
56
-
operations, when persisted operations are unsupported the server can change the error message to `PersistedOperationNotSupported`.
57
-
58
-
The client is made aware of the server not knowing the document we are dealing with by means of this error, the client can now send
59
-
a new request containing both `documentId` and `query` in the parameters to make the server aware of the correlation. The server can
60
-
verify that the `documentId` and `query` are correctly being associated by performing the stringify and hash steps, to avoid
61
-
malicious actors inserting faux associations.
62
-
63
-
The server can now save the association between the `documentId` and `query` for future requests.
0 commit comments