relay icon indicating copy to clipboard operation
relay copied to clipboard

Client schema interface extension are not taken into account by the compiler

Open kawazoe opened this issue 4 months ago • 0 comments

Relay: v16

Given the following schemas:

// schema.graphql
type Query {
  foos: [Foo]!
}
type Foo {
  id: ID!
}

// clientSchema.graphql
interface Labeled {
  label: String!
}

extend type Foo implements Labeled

Given the following (experimental) relay resolver, though I expect you might have the same problem by implementing label in the Foo extension explicitly:

/**
 * @RelayResolver Foo.label(): String
 * @rootFragment FooLabelResolver
 */
export function label($key: FooLabelResolver$key): string {
  const $data = readFragment(
    graphql`
      fragment FooLabelResolver on Foo {
        id
      }
    `,
    $key,
  );
  return `${$data.id}`;
}

Given the following queries:

graphql`
  fragment FooLabeledFragment on Labeled {
    label
  }
`;

graphql`
  query {
    foos {
      ...FooLabeledFragment
    }
  }
`;

The compiler produces the following error, hinting that it did not took into consideration the added interface:

Invalid fragment spread 'FooLabeledFragment', the type of this fragment ('Labeled') can never occur for parent type 'Foo'

As mentioned, I suspect that declaring the label field explicitely instead of via a client resolver wouldn't change the outcome, since the compiler complains about the schema missing the implementation of the interface before even producing errors about a missing field.

As a secondary issue, this kind of extensions using the experimental resolvers would benefit from some DX improvements. Right now, trying to define the label field explicitly cause the compiler to fail to generate the resolver as it already exists in the schema. This also means that whatever tooling the dev is using, like the webstorm graphql extension, isn't aware of those extra resolvers and will report errors in the queries even if they technically work. I think this could be avoided by generating a graphql file together with the tsx file as a client extension. The field in that file could have a special flag (via a comment maybe?) that would mark it as handled by a relay resolver which would effectively silence the error for the double declaration of the field. With this in place, relay resolvers would act like any other client extensions schema wise and I think it would greatly improve the kind of thing I'm trying to accomplish here.

kawazoe avatar Feb 01 '24 17:02 kawazoe