apollographql / apollographql/apollo-utils

generate-persisted-query-manifest doesn't match operations built by Apollo Client (fragments)

Open
#498 15 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
42
Forks
14
PR merge metrics
No merged PRs in 30d

Description

Hey there 👋

I'm using `@apollo/client` version `3.10.6` and `@apollo/generate-persisted-query-manifest` version `1.3.0`.

Consider code like the following:
```index.gql.js
// From index.gql.js
const LocationFieldsFragment = gql`
fragment LocationFieldsFragment on Location {
id
uuid
name
address
coordinates {
latitude
longitude
}
zip_code
}
`;

const SomeFragment = gql`
fragment SomeFragment on Profile {
fullName
locations {
edges {
node {
...LocationFieldsFragment
}
}
}
}
${LocationFieldsFragment}
`;

const FoobarQuery = gql`
query Foobar($uuid: ID) {
profile(uuid: $uuid) {
id
...SomeFragment
}
}
${SomeFragment}
`;
```

The query generated (and hashed) by running `yarn generate-persisted-query-manifest` looks like this:

```graphql
query Foobar($uuid: ID) {
profile(uuid: $uuid) {
id
...SomeFragment
__typename
}
}
fragment LocationFieldsFragment on Location {
id
uuid
name
address
coordinates {
latitude
longitude
__typename
}
zip_code
phone_number
__typename
}
fragment SomeFragment on Profile {
fullName
locations {
edges {
node {
...LocationFieldsFragment
__typename
}
__typename
}
__typename
}
__typename
}
```

While Apollo Client generates and performs the following query:

```graphql
query Foobar($uuid: ID) {
profile(uuid: $uuid) {
id
...SomeFragment
__typename
}
}
fragment SomeFragment on Profile {
fullName
locations {
edges {
node {
...LocationFieldsFragment
__typename
}
__typename
}
__typename
}
__typename
}
fragment LocationFieldsFragment on Location {
id
uuid
name
address
coordinates {
latitude
longitude
__typename
}
zip_code
phone_number
__typename
}
```

The only difference between both queries above is the ordering of declarations: Apollo Client has the `LocationFieldsFragment` declared at the bottom, while `yarn generate-persisted-query-manifest` has `SomeFragment` at the bottom — this divergence results in different digests.

I'm not sure if there is a standard around what's really expected here but I assume this tool should be doing what Apollo Client expects else anyone trying to implement a safelist of GraphQL operations through persisted queries is in big trouble (our case).

Any ideas on the above?

Thank you,
Nicholas

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with the `index.gql.js` fragments and the `yarn generate-persisted-query-manifest` command, then compare its manifest query with Apollo Client's generated operation. Trace the manifest generation entry point to determine how fragment declarations are ordered; done means matching Apollo Client's declaration order and resulting digest, with regression coverage for nested fragments.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, typescript
Domain
api, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.