Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegate removes selection sets when nesting Top-Level Abstract Fields in a Mutation response #4945

Open
Tracked by #5201 ...
FlorianRohm opened this issue Jan 4, 2023 · 2 comments

Comments

@FlorianRohm
Copy link

Hi, we have a graphql API with the following structure

interface Foo {
   pk: ID
}
type Bar implements Foo {
   pk: ID
   bar: String
}

type Nested {
   foo: Foo
}

type Query {
  foo: Foo
  nested: Nested
}

type MutationResponseType {
  query: Query
}

type Mutation {
   someMutation(pk: ID!): MutationResponseType
}

Describe the bug

When using the mutation with a Fragment on Query, fields of the Interface are removed when used on top level. I.e.

mutation SomeMutation {
    someMutation(id: "234") {
        query {
            ...MyFragment
        }
    }
}

fragment MyFragment on Query {
    foo {
        ... on Bar {
           pk
        }
    }
}

gets transformed to

mutation SomeMutation {
    someMutation(id: "234") {
        __typename
        query {
            __typename
            ...MyFragment
        }
    }
}

fragment MyFragment on Query {
    foo {
         __typename
    }
}

This does not happen when either the Fragment is not on top level or the Interface is nested. I.e. the following work:

mutation SomeMutation {
    someMutation(id: "234") {
        query {
            foo {
              ...NotTopLevel
            }
            ...MyFragment
        }
    }
}

fragment NotTopLevel on Foo {
      ... on Bar {
         pk
      }
}

fragment Nested on Query {
    nested { 
        foo {
            ... on Bar {
               pk
            } 
        }
    }
}

To Reproduce
Steps to reproduce the behavior:

I tried to write a test in the repo but did not succeed with providing the right test-input.

However, with a working client on our actual production code I was able to debug into it and find out where it goes wrong for us:
In wrapConcreteTypes in prepareGatewayDocument.ts, you create new selections and set the type conditions. However, this type gets set to MutationReturnType.
grafik

This causes problems later down the line in finalizeSelectionSet where the fields are discarded, as the types do not match (sorry for the ugly screenshot, had to wipe our internal names). I think , there should be the implementing type instead of the second Type, i.e. Bar.
grafik

When I comment out the FIELD visitor in wrapConcreteTypes, everything works as expected (well, for our small case).

Hope that helps even if I could not provide a minimum reproducible version.

Expected behavior

Valid attributes should not be discarded

Environment:

  • @graphql-tools/delegate: 9.0.21
  • NodeJS: LTS Gallium
@ardatan
Copy link
Owner

ardatan commented Jan 4, 2023

I tried to write a test in the repo but did not succeed with providing the right test-input.

Could you give more details about this? What didn't work?

@FlorianRohm
Copy link
Author

I was not able to create a fitting testsetup.
Creating a test which uses finalizeGatewayRequest as entrypoint was easy (see trying_to_test.patch), but the problem resides in prepareGatewayDocument.ts. Searching for a test-entry, I found the transforms.test.ts where I tried to hook into (see trying_to_test,_pt_2.patch). There, however I would have create a delegation context which I was not able to.

The tests I did in the client project was using gql from apollo-server-express to create the DocumentNode, executing this on a server with a httpLink and observing the request apollo is trying to send.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants