Skip to content

Commit fa2f2fa

Browse files
fix(federation): Composition propagates @deprecated usages on input type object fields (#1008)
Update graphql peer dependency, introduce new test scenarios to validate the fix.
1 parent 8cabe69 commit fa2f2fa

File tree

18 files changed

+185
-52
lines changed

18 files changed

+185
-52
lines changed

federation-integration-testsuite-js/src/fixtures/reviews.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,14 @@ export const typeDefs = gql`
7474
retailPrice: String @requires(fields: "price")
7575
}
7676
77+
input ReviewProduct {
78+
upc: String!
79+
body: String!
80+
stars: Int @deprecated(reason: "Stars are no longer in use")
81+
}
82+
7783
extend type Mutation {
78-
reviewProduct(upc: String!, body: String!): Product
84+
reviewProduct(input: ReviewProduct!): Product
7985
updateReview(review: UpdateReviewInput!): Review
8086
deleteReview(id: ID!): Boolean
8187
}
@@ -157,7 +163,7 @@ export const resolvers: GraphQLResolverMap<any> = {
157163
},
158164
},
159165
Mutation: {
160-
reviewProduct(_, { upc, body }) {
166+
reviewProduct(_, { input: { upc, body } }) {
161167
const id = `${Number(reviews[reviews.length - 1].id) + 1}`;
162168
reviews.push({
163169
id,
@@ -168,7 +174,7 @@ export const resolvers: GraphQLResolverMap<any> = {
168174
return { upc, __typename: 'Furniture' };
169175
},
170176
updateReview(_, { review: { id }, review: updatedReview }) {
171-
let review = reviews.find(review => review.id === id);
177+
let review = reviews.find((review) => review.id === id);
172178

173179
if (!review) {
174180
return null;
@@ -183,7 +189,7 @@ export const resolvers: GraphQLResolverMap<any> = {
183189
},
184190
deleteReview(_, { id }) {
185191
const deleted = reviews.splice(
186-
reviews.findIndex(review => review.id === id),
192+
reviews.findIndex((review) => review.id === id),
187193
1,
188194
);
189195
return Boolean(deleted);
@@ -196,13 +202,13 @@ export const resolvers: GraphQLResolverMap<any> = {
196202
},
197203
User: {
198204
reviews(user) {
199-
return reviews.filter(review => review.authorID === user.id);
205+
return reviews.filter((review) => review.authorID === user.id);
200206
},
201207
numberOfReviews(user) {
202-
return reviews.filter(review => review.authorID === user.id).length;
208+
return reviews.filter((review) => review.authorID === user.id).length;
203209
},
204210
username(user) {
205-
const found = usernames.find(username => username.id === user.id);
211+
const found = usernames.find((username) => username.id === user.id);
206212
return found ? found.username : null;
207213
},
208214
goodAddress(object) {
@@ -211,18 +217,18 @@ export const resolvers: GraphQLResolverMap<any> = {
211217
},
212218
Furniture: {
213219
reviews(product) {
214-
return reviews.filter(review => review.product.upc === product.upc);
220+
return reviews.filter((review) => review.product.upc === product.upc);
215221
},
216222
},
217223
Book: {
218224
reviews(product) {
219-
return reviews.filter(review => review.product.isbn === product.isbn);
225+
return reviews.filter((review) => review.product.isbn === product.isbn);
220226
},
221227
relatedReviews(book) {
222228
return book.similarBooks
223229
? book.similarBooks
224230
.map(({ isbn }: any) =>
225-
reviews.filter(review => review.product.isbn === isbn),
231+
reviews.filter((review) => review.product.isbn === isbn),
226232
)
227233
.flat()
228234
: [];

federation-integration-testsuite-js/src/fixtures/special-cases/reviewsWithoutTag.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,14 @@ export const typeDefs = gql`
6767
retailPrice: String @requires(fields: "price")
6868
}
6969
70+
input ReviewProduct {
71+
upc: String!
72+
body: String!
73+
stars: Int @deprecated(reason: "Stars are no longer in use")
74+
}
75+
7076
extend type Mutation {
71-
reviewProduct(upc: String!, body: String!): Product
77+
reviewProduct(input: ReviewProduct): Product
7278
updateReview(review: UpdateReviewInput!): Review
7379
deleteReview(id: ID!): Boolean
7480
}

federation-js/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
> The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. When a release is being prepared, a new header will be (manually) created below and the appropriate changes within that release will be moved into the new section.
66
7-
- _Nothing yet! Stay tuned!_
7+
- __BREAKING__: This is a breaking change due to a `peerDependencies` update (`graphql@^15.4.0` -> `graphql@^15.5.3`). This `graphql` version includes a fix which resolves an issue which prevented the correct propagation of `@deprecated` usages on input type object fields into the printed subgraph schema. This can be considered a follow-up to PR #996, which previously attempted to propagate @deprecated on *ALL* input values. [PR #1008](https://github.com/apollographql/federation/pull/1008)
88

99
## v0.31.0
1010

federation-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@
2828
"lodash.xorby": "^4.7.0"
2929
},
3030
"peerDependencies": {
31-
"graphql": "^15.4.0"
31+
"graphql": "^15.5.3"
3232
}
3333
}

federation-js/src/service/__tests__/printSubgraphSchema.test.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,102 @@ describe('printSubgraphSchema', () => {
7474
"
7575
`);
7676
});
77+
78+
it('prints reviews subgraph correctly', () => {
79+
const schema = buildSubgraphSchema(fixtures[5].typeDefs);
80+
expect(printSubgraphSchema(schema)).toMatchInlineSnapshot(`
81+
"directive @stream on FIELD
82+
83+
directive @transform(from: String!) on FIELD
84+
85+
type Review @key(fields: \\"id\\") {
86+
id: ID!
87+
body(format: Boolean = false): String
88+
author: User @provides(fields: \\"username\\")
89+
product: Product
90+
metadata: [MetadataOrError]
91+
}
92+
93+
input UpdateReviewInput {
94+
id: ID!
95+
body: String
96+
}
97+
98+
input ReviewProduct {
99+
upc: String!
100+
body: String!
101+
stars: Int @deprecated(reason: \\"Stars are no longer in use\\")
102+
}
103+
104+
type KeyValue {
105+
key: String!
106+
value: String!
107+
}
108+
109+
type Error {
110+
code: Int
111+
message: String
112+
}
113+
114+
union MetadataOrError = KeyValue | Error
115+
116+
extend type Query {
117+
_entities(representations: [_Any!]!): [_Entity]!
118+
_service: _Service!
119+
topReviews(first: Int = 5): [Review]
120+
}
121+
122+
extend type UserMetadata {
123+
address: String @external
124+
}
125+
126+
extend type User @key(fields: \\"id\\") {
127+
id: ID! @external
128+
username: String @external
129+
reviews: [Review]
130+
numberOfReviews: Int!
131+
metadata: [UserMetadata] @external
132+
goodAddress: Boolean @requires(fields: \\"metadata { address }\\")
133+
}
134+
135+
extend interface Product {
136+
reviews: [Review]
137+
}
138+
139+
extend type Furniture implements Product @key(fields: \\"upc\\") {
140+
upc: String! @external
141+
reviews: [Review]
142+
}
143+
144+
extend type Book implements Product @key(fields: \\"isbn\\") {
145+
isbn: String! @external
146+
reviews: [Review]
147+
similarBooks: [Book]! @external
148+
relatedReviews: [Review!]! @requires(fields: \\"similarBooks { isbn }\\")
149+
}
150+
151+
extend interface Vehicle {
152+
retailPrice: String
153+
}
154+
155+
extend type Car implements Vehicle @key(fields: \\"id\\") {
156+
id: String! @external
157+
price: String @external
158+
retailPrice: String @requires(fields: \\"price\\")
159+
}
160+
161+
extend type Van implements Vehicle @key(fields: \\"id\\") {
162+
id: String! @external
163+
price: String @external
164+
retailPrice: String @requires(fields: \\"price\\")
165+
}
166+
167+
extend type Mutation {
168+
reviewProduct(input: ReviewProduct!): Product
169+
updateReview(review: UpdateReviewInput!): Review
170+
deleteReview(id: ID!): Boolean
171+
}
172+
"
173+
`);
174+
});
77175
});

federation-js/src/service/__tests__/printSupergraphSdl.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ describe('printSupergraphSdl', () => {
163163
type Mutation {
164164
deleteReview(id: ID!): Boolean @join__field(graph: REVIEWS)
165165
login(password: String!, userId: String @deprecated(reason: \\"Use username instead\\"), username: String!): User @join__field(graph: ACCOUNTS)
166-
reviewProduct(body: String!, upc: String!): Product @join__field(graph: REVIEWS)
166+
reviewProduct(input: ReviewProduct!): Product @join__field(graph: REVIEWS)
167167
updateReview(review: UpdateReviewInput!): Review @join__field(graph: REVIEWS)
168168
}
169169
@@ -234,6 +234,12 @@ describe('printSupergraphSdl', () => {
234234
product: Product @join__field(graph: REVIEWS)
235235
}
236236
237+
input ReviewProduct {
238+
body: String!
239+
stars: Int @deprecated(reason: \\"Stars are no longer in use\\")
240+
upc: String!
241+
}
242+
237243
type SMSAccount
238244
@join__owner(graph: ACCOUNTS)
239245
@join__type(graph: ACCOUNTS, key: \\"number\\")
@@ -471,7 +477,7 @@ describe('printSupergraphSdl', () => {
471477
type Mutation {
472478
deleteReview(id: ID!): Boolean @join__field(graph: REVIEWS)
473479
login(password: String!, username: String!): User @join__field(graph: ACCOUNTS)
474-
reviewProduct(body: String!, upc: String!): Product @join__field(graph: REVIEWS)
480+
reviewProduct(input: ReviewProduct): Product @join__field(graph: REVIEWS)
475481
updateReview(review: UpdateReviewInput!): Review @join__field(graph: REVIEWS)
476482
}
477483
@@ -540,6 +546,12 @@ describe('printSupergraphSdl', () => {
540546
product: Product @join__field(graph: REVIEWS)
541547
}
542548
549+
input ReviewProduct {
550+
body: String!
551+
stars: Int @deprecated(reason: \\"Stars are no longer in use\\")
552+
upc: String!
553+
}
554+
543555
type SMSAccount
544556
@join__owner(graph: ACCOUNTS)
545557
@join__type(graph: ACCOUNTS, key: \\"number\\")

federation-js/src/service/printSubgraphSchema.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,6 @@ import { federationDirectives, gatherDirectives } from '../directives';
3939
*/
4040
export const printSchema = printSubgraphSchema;
4141

42-
/**
43-
* Accepts options as a second argument:
44-
*
45-
* - commentDescriptions:
46-
* Provide true to use preceding comments as the description.
47-
*/
4842
export function printSubgraphSchema(schema: GraphQLSchema): string {
4943
return printFilteredSchema(
5044
schema,

gateway-js/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
> The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. When a release is being prepared, a new header will be (manually) created below and the appropriate changes within that release will be moved into the new section.
66
7-
- _Nothing yet! Stay tuned!_
7+
- __BREAKING__: This is a breaking change due to a `peerDependencies` update (`graphql@^15.4.0` -> `graphql@^15.5.3`). This `graphql` version includes a fix which is being necessarily adopted within the `@apollo/federation` package. See associated CHANGELOG entry in the `federation-js` folder for additional details. [PR #1008](https://github.com/apollographql/federation/pull/1008)
88

99
## v0.40.0
1010

gateway-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@
4242
"pretty-format": "^26.0.0"
4343
},
4444
"peerDependencies": {
45-
"graphql": "^15.4.0"
45+
"graphql": "^15.5.3"
4646
}
4747
}

gateway-js/src/__tests__/build-query-plan.feature

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,7 +1066,7 @@ Scenario: returning across service boundaries
10661066
Given query
10671067
"""
10681068
mutation Review($upc: String!, $body: String!) {
1069-
reviewProduct(upc: $upc, body: $body) {
1069+
reviewProduct(input: {upc: $upc, body: $body}) {
10701070
... on Furniture {
10711071
name
10721072
}
@@ -1087,7 +1087,7 @@ Scenario: returning across service boundaries
10871087
"upc",
10881088
"body"
10891089
],
1090-
"operation": "mutation($upc:String!$body:String!){reviewProduct(upc:$upc body:$body){__typename ...on Furniture{__typename upc}}}"
1090+
"operation": "mutation($upc:String!$body:String!){reviewProduct(input:{upc:$upc body:$body}){__typename ...on Furniture{__typename upc}}}"
10911091
},
10921092
{
10931093
"kind": "Flatten",
@@ -1139,7 +1139,7 @@ Scenario: supports multiple root mutations
11391139
}
11401140
}
11411141
}
1142-
reviewProduct(upc: $upc, body: $body) {
1142+
reviewProduct(input: {upc: $upc, body: $body}) {
11431143
... on Furniture {
11441144
name
11451145
}
@@ -1228,7 +1228,7 @@ Scenario: supports multiple root mutations
12281228
"upc",
12291229
"body"
12301230
],
1231-
"operation": "mutation($upc:String!$body:String!){reviewProduct(upc:$upc body:$body){__typename ...on Furniture{__typename upc}}}"
1231+
"operation": "mutation($upc:String!$body:String!){reviewProduct(input:{upc:$upc body:$body}){__typename ...on Furniture{__typename upc}}}"
12321232
},
12331233
{
12341234
"kind": "Flatten",
@@ -1275,7 +1275,7 @@ Scenario: multiple root mutations with correct service order
12751275
$password: String!
12761276
$reviewId: ID!
12771277
) {
1278-
reviewProduct(upc: $upc, body: $body) {
1278+
reviewProduct(input: {upc: $upc, body: $body}) {
12791279
... on Furniture {
12801280
upc
12811281
}
@@ -1309,7 +1309,7 @@ Scenario: multiple root mutations with correct service order
13091309
"body",
13101310
"updatedReview"
13111311
],
1312-
"operation": "mutation($upc:String!$body:String!$updatedReview:UpdateReviewInput!){reviewProduct(upc:$upc body:$body){__typename ...on Furniture{upc}}updateReview(review:$updatedReview){id body}}"
1312+
"operation": "mutation($upc:String!$body:String!$updatedReview:UpdateReviewInput!){reviewProduct(input:{upc:$upc body:$body}){__typename ...on Furniture{upc}}updateReview(review:$updatedReview){id body}}"
13131313
},
13141314
{
13151315
"kind": "Fetch",

0 commit comments

Comments
 (0)