Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions __tests__/__snapshots__/integration.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,6 @@ interface Node {
}

type Query {
"""
Exposes the root query type nested one level down. This is helpful for Relay 1
which can only query top level fields if they are in a particular form.
"""
query: Query!

"""
The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`.
"""
nodeId: ID!

"""Fetches an object given its globally unique \`ID\`."""
node(
"""The globally unique \`ID\`."""
nodeId: ID!
): Node

"""Reads a set of \`Email\`."""
allEmailsList(
"""Only read the first \`n\` values of the set."""
Expand Down
52 changes: 9 additions & 43 deletions __tests__/__snapshots__/schema.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,6 @@ interface Node {

\\"\\"\\"The root query type which gives access points into the data universe.\\"\\"\\"
type Query {
\\"\\"\\"
Exposes the root query type nested one level down. This is helpful for Relay 1
which can only query top level fields if they are in a particular form.
\\"\\"\\"
query: Query!

\\"\\"\\"
The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`.
\\"\\"\\"
nodeId: ID!

\\"\\"\\"Fetches an object given its globally unique \`ID\`.\\"\\"\\"
node(
\\"\\"\\"The globally unique \`ID\`.\\"\\"\\"
nodeId: ID!
): Node

\\"\\"\\"Reads a set of \`Email\`.\\"\\"\\"
allEmailsList(
\\"\\"\\"Only read the first \`n\` values of the set.\\"\\"\\"
Expand Down Expand Up @@ -255,24 +238,7 @@ directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
directive @key(fields: _FieldSet!) on OBJECT | INTERFACE

"""The root query type which gives access points into the data universe."""
type Query implements Node {
"""
Exposes the root query type nested one level down. This is helpful for Relay 1
which can only query top level fields if they are in a particular form.
"""
query: Query!

"""
The root query type must be a \`Node\` to work well with Relay 1 mutations. This just resolves to \`query\`.
"""
nodeId: ID!

"""Fetches an object given its globally unique \`ID\`."""
node(
"""The globally unique \`ID\`."""
nodeId: ID!
): Node

type Query {
"""Reads a set of \`Email\`."""
allEmailsList(
"""Only read the first \`n\` values of the set."""
Expand Down Expand Up @@ -360,14 +326,6 @@ type Query implements Node {
_service: _Service! @deprecated(reason: "Only Apollo Federation should use this")
}

"""An object with a globally unique \`ID\`."""
interface Node {
"""
A globally unique identifier. Can be used in various places throughout the system to identify this single value.
"""
nodeId: ID!
}

type Email implements Node {
"""
A globally unique identifier. Can be used in various places throughout the system to identify this single value.
Expand All @@ -394,6 +352,14 @@ type Email implements Node {
): [UsersEmail!]!
}

"""An object with a globally unique \`ID\`."""
interface Node {
"""
A globally unique identifier. Can be used in various places throughout the system to identify this single value.
"""
nodeId: ID!
}

type UsersEmail implements Node {
"""
A globally unique identifier. Can be used in various places throughout the system to identify this single value.
Expand Down
37 changes: 35 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,41 @@ const AddKeyPlugin: Plugin = builder => {
});
};

// Our federation implementation combines these two plugins:
/*
* This plugin remove query/node/nodeId fields and Node interface from Query type to
* fix `GraphQLSchemaValidationError: There can be only one type named "query/node/nodeId"` error.
* This helps Apollo Gateway to consume two or more PostGraphile services.
*/

const RemoveQueryLegacyFeaturesPlugin: Plugin = builder => {
builder.hook('GraphQLObjectType:fields', (fields, _, context) => {
const {
scope: { isRootQuery },
} = context;

// Deleting the query, node, nodeId fields from the Query type that are used by
// the old relay specification which are not needed for modern GraphQL clients
if (isRootQuery) {
delete fields.query;
delete fields.node;
delete fields.nodeId;
}

return fields;
});

builder.hook('GraphQLObjectType:interfaces', (interfaces, _, context) => {
if (!context.scope.isRootQuery) {
return interfaces;
}
// Delete all interfaces (i.e. the Node interface) from Query.
return [];
});
};

// Our federation implementation combines these plugins:
export default makePluginByCombiningPlugins(
SchemaExtensionPlugin,
AddKeyPlugin
AddKeyPlugin,
RemoveQueryLegacyFeaturesPlugin,
);