AEB-labs / graphql-weaver

A tool to combine, link and transform GraphQL schemas
MIT License
240 stars 20 forks source link

Query root type duplicate #19

Open terion-name opened 6 years ago

terion-name commented 6 years ago

Root types (query, mutation, etc) should be merged, yes? But I am trying to do the following: combining apollo server with schema stiching and weaver like this (a demo):

const link = new HttpLink({uri: 'https://graphql-demo.azurewebsites.net/graphql', fetch});

  const remoteSchema = await introspectSchema(link);

  const executableSchema = makeRemoteExecutableSchema({
    schema: remoteSchema,
    link,
  });

  const transformedSchema = await weaveSchemas({
    endpoints: [{
      // typePrefix: 'Demo__',
      namespace: 'demo',
      schema: executableSchema
    }]
  });

And I get:

(node:5997) UnhandledPromiseRejectionWarning: Error: Schema must contain unique named types but contains multiple types named "Query".

Even without apollo's tooling, like this:

const transformedSchema = await weaveSchemas({
      endpoints: [{
        namespace: 'demo',
        url:  'https://graphql-demo.azurewebsites.net/graphql'
      }]
    });

I get the same.

If I add typePrefix, schema becomes strange:

Query → demo → Demo__Query → ...  stuff

While queries perform correctly, I don't understand, why this conflict in root types appears (especially if to consider that I try it with one endpoint)

Yogu commented 6 years ago

You are correct, root types are merged. However, if you specify a namespace, its root types are wrapped in a field on the newly generated root type first - thus, you have two query types:

# newly generated query type
type Query {
  demo: Query # referencing the original Query type of demo
}

# the original Query type of demo
type Query {
  // original fields of demo's Query type
}

This generates the error about duplicate types you got. You should use typePrefix in conjunction with namespaces to avoid these kind of conflicts. I could also see an extension to graphql-weaver that allows to specify the names of the newly generated root types, so you could disambiguate the two types - but this would fail with the next endpoint as it probably also has a Query type. Or you could just rename the Query type in the referenced schema if it is controlled by you.

If I add typePrefix, schema becomes strange:

Query → demo → Demo__Query → ...  stuff

While queries perform correctly, I don't understand, why this conflict in root types appears (especially if to consider that I try it with one endpoint)

I don't know what you mean by Demo__Query. I reproduced your setup in apollo launchpad. It works as intended, and there is no Demo__Query type if this is what you meant.

terion-name commented 6 years ago

You should use typePrefix in conjunction with namespaces to avoid these kind of conflicts

understood, thank you

I don't know what you mean by Demo__Query

This:

2018-01-17 11 41 53 2018-01-17 11 42 00

But yes, queries work ok:

2018-01-17 11 44 57

And this looks strange

Yogu commented 6 years ago

Ah, I only just realized you used Demo__ as typePrefix. I wondered where these two underscores come from ;)

What exactly does look strange to you, then? The Query type is the root type and contains a field for the namespace demo of type Demo__Query, which is just the renamed type Query from your endpoint.

In case you are referring to _extIntrospection - this is a field required for the @link and @join features. We could also add an option to exclude this from the output if it bothers you.