Skip to content

Commit

Permalink
fix(federation): handle key fields even if they are not explicitly de…
Browse files Browse the repository at this point in the history
…fined as a field
  • Loading branch information
ardatan committed Mar 12, 2024
1 parent 7636ce5 commit 4620bb2
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/late-books-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@graphql-tools/federation": patch
---

Handle unspecified key fields
15 changes: 15 additions & 0 deletions packages/federation/src/supergraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export function getSubschemasFromSupergraphSdl({
const joinFieldDirectives = fieldNode.directives?.filter(
directiveNode => directiveNode.name.value === 'join__field',
);
let notInSubgraph = true;
joinFieldDirectives?.forEach(joinFieldDirectiveNode => {
const joinFieldGraphArgNode = joinFieldDirectiveNode.arguments?.find(
argumentNode => argumentNode.name.value === 'graph',
Expand All @@ -146,6 +147,7 @@ export function getSubschemasFromSupergraphSdl({
joinFieldGraphArgNode?.value?.kind === Kind.ENUM &&
joinFieldGraphArgNode.value.value === graphName
) {
notInSubgraph = false;
const isExternal = joinFieldDirectiveNode.arguments?.some(
argumentNode =>
argumentNode.name.value === 'external' &&
Expand Down Expand Up @@ -220,6 +222,19 @@ export function getSubschemasFromSupergraphSdl({
directiveNode => directiveNode.name.value !== 'join__field',
),
});
} else if (
notInSubgraph &&
typeNameKeysBySubgraphMap
.get(graphName)
?.get(typeNode.name.value)
?.some(key => key.split(' ').includes(fieldNode.name.value))
) {
fieldDefinitionNodesOfSubgraph.push({
...fieldNode,
directives: fieldNode.directives?.filter(
directiveNode => directiveNode.name.value !== 'join__field',
),
});
}
});
if (fieldDefinitionNodesOfSubgraph.length > 0 || typeNode.name.value === 'Query') {
Expand Down
41 changes: 38 additions & 3 deletions packages/federation/test/__snapshots__/supergraphs.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ type Query {
}
type User {
id: ID!
numberOfReviews: Int
reviews: [Review]
username: String
birthDate: String
id: ID!
name: String
}
type Product {
reviews(input: ProductReviewsInput): [Review]
upc: String!
inStock: Boolean
shippingEstimate: Int
name: String
price: Int
upc: String!
weight: Int
}
Expand Down Expand Up @@ -131,6 +131,7 @@ type AnonymousReview implements Review {
type Product {
reviews(input: ProductReviewsInput): [Review]
upc: String!
}
type Query {
Expand All @@ -146,6 +147,7 @@ interface Review {
scalar Stars
type User {
id: ID!
numberOfReviews: Int
reviews: [Review]
username: String
Expand All @@ -172,6 +174,7 @@ exports[`Supergraphs a.graphql subgraphs: a.graphql - SERVICE3 1`] = `
type Product {
inStock: Boolean
shippingEstimate: Int
upc: String!
}
type Query {
Expand Down Expand Up @@ -540,6 +543,11 @@ type Handle implements Node {
mentionable: Mentionable
}
type Member implements Node {
id: ID!
email: String!
}
interface Node {
id: ID!
}
Expand Down Expand Up @@ -601,6 +609,11 @@ type Handle implements Node {
mentionable: Mentionable
}
type Member implements Node {
id: ID!
email: String!
}
interface Node {
id: ID!
}
Expand All @@ -621,7 +634,29 @@ enum NotifiableEntityType {
ITEM
}
union _Entity = ReactionAuthor | Handle
union _Entity = ReactionAuthor | Handle | Member
scalar _Any"
`;

exports[`Supergraphs d.graphql subgraphs: d.graphql - PB_SERVICE_B 1`] = `
"schema {
query: Query
}
type Query {
_entities(representations: [_Any!]!): _Entity
}
type Member implements Node {
id: ID!
}
interface Node {
id: ID!
}
union _Entity = Member
scalar _Any"
`;
9 changes: 9 additions & 0 deletions packages/federation/test/fixtures/supergraphs/d.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ type Handle implements Node
mentionable: Mentionable @join__field(graph: PB_BACKEND)
}

type Member implements Node
@join__owner(graph: PB_BACKEND)
@join__type(graph: PB_BACKEND, key: "id")
@join__type(graph: PB_SERVICE_B, key: "id") {
id: ID! @join__field(graph: PB_BACKEND)
email: String! @join__field(graph: PB_BACKEND)
}

union Mentionable = ReactionAuthor | OwnerChangedNotification

enum core__Purpose {
Expand All @@ -82,4 +90,5 @@ enum join__Graph {
NODERESOLVER
@join__graph(name: "noderesolver", url: "http://graphql-node-resolver.graphql/graphql")
PB_BACKEND @join__graph(name: "pb-backend", url: "http://pb-backend-web.default/internal/graphql")
PB_SERVICE_B @join__graph(name: "pb-service-b", url: "http://pb-service-b.default/graphql")
}

0 comments on commit 4620bb2

Please sign in to comment.