From 198270bddc7f3ce9259ebfe284944fcc3ad5abc4 Mon Sep 17 00:00:00 2001 From: Hannes Junnila Date: Mon, 17 Jun 2019 16:32:26 +0300 Subject: [PATCH] Always send variables required for query --- .../__fixtures__/schemas/accounts.ts | 7 +- .../src/__tests__/executeQueryPlan.test.ts | 69 +++++++++++++++++++ .../apollo-gateway/src/executeQueryPlan.ts | 28 ++++---- 3 files changed, 91 insertions(+), 13 deletions(-) diff --git a/packages/apollo-gateway/src/__tests__/__fixtures__/schemas/accounts.ts b/packages/apollo-gateway/src/__tests__/__fixtures__/schemas/accounts.ts index a83051883e5..895df51557e 100644 --- a/packages/apollo-gateway/src/__tests__/__fixtures__/schemas/accounts.ts +++ b/packages/apollo-gateway/src/__tests__/__fixtures__/schemas/accounts.ts @@ -22,7 +22,7 @@ export const typeDefs = gql` id: ID! name: String username: String - birthDate: String + birthDate(locale: String): String account: AccountType } @@ -62,6 +62,11 @@ export const resolvers: GraphQLResolverMap = { __resolveObject(object) { return users.find(user => user.id === object.id); }, + birthDate(user, args) { + return args.locale + ? new Date(user.birthDate).toLocaleDateString(args.locale) + : user.birthDate; + }, }, Mutation: { login(_, args) { diff --git a/packages/apollo-gateway/src/__tests__/executeQueryPlan.test.ts b/packages/apollo-gateway/src/__tests__/executeQueryPlan.test.ts index 767b242616f..a8d5699c2be 100644 --- a/packages/apollo-gateway/src/__tests__/executeQueryPlan.test.ts +++ b/packages/apollo-gateway/src/__tests__/executeQueryPlan.test.ts @@ -325,6 +325,75 @@ describe('executeQueryPlan', () => { `); }); + it('should include variables in non-root requests', async () => { + const query = gql` + query Test($locale: String) { + topReviews { + body + author { + name + birthDate(locale: $locale) + } + } + } + `; + + const operationContext = buildOperationContext(schema, query); + const queryPlan = buildQueryPlan(operationContext); + + const requestContext = buildRequestContext(); + requestContext.request.variables = { locale: 'en-US' }; + + const response = await executeQueryPlan( + queryPlan, + serviceMap, + requestContext, + operationContext, + ); + + expect(response.data).toMatchInlineSnapshot(` + Object { + "topReviews": Array [ + Object { + "author": Object { + "birthDate": "12/10/1815", + "name": "Ada Lovelace", + }, + "body": "Love it!", + }, + Object { + "author": Object { + "birthDate": "12/10/1815", + "name": "Ada Lovelace", + }, + "body": "Too expensive.", + }, + Object { + "author": Object { + "birthDate": "6/23/1912", + "name": "Alan Turing", + }, + "body": "Could be better.", + }, + Object { + "author": Object { + "birthDate": "6/23/1912", + "name": "Alan Turing", + }, + "body": "Prefer something else.", + }, + Object { + "author": Object { + "birthDate": "6/23/1912", + "name": "Alan Turing", + }, + "body": "Wish I had read this before.", + }, + ], + } + `); + }); + it('can execute an introspection query', async () => { const operationContext = buildOperationContext( schema, diff --git a/packages/apollo-gateway/src/executeQueryPlan.ts b/packages/apollo-gateway/src/executeQueryPlan.ts index f296e6d5e0c..1f3ee44d35d 100644 --- a/packages/apollo-gateway/src/executeQueryPlan.ts +++ b/packages/apollo-gateway/src/executeQueryPlan.ts @@ -150,20 +150,20 @@ async function executeFetch( const entities = Array.isArray(results) ? results : [results]; if (entities.length < 1) return; - if (!fetch.requires) { - let variables = Object.create(null); - if (fetch.variableUsages) { - for (const { node, defaultValue } of fetch.variableUsages) { - const name = node.name.value; - const providedVariables = context.requestContext.request.variables; - if (providedVariables && providedVariables[name] !== 'undefined') { - variables[name] = providedVariables[name]; - } else if (defaultValue) { - variables[name] = defaultValue; - } + let variables = Object.create(null); + if (fetch.variableUsages) { + for (const { node, defaultValue } of fetch.variableUsages) { + const name = node.name.value; + const providedVariables = context.requestContext.request.variables; + if (providedVariables && providedVariables[name] !== 'undefined') { + variables[name] = providedVariables[name]; + } else if (defaultValue) { + variables[name] = defaultValue; } } + } + if (!fetch.requires) { const dataReceivedFromService = await sendOperation( context, operationForRootFetch(fetch, operationType), @@ -187,10 +187,14 @@ async function executeFetch( } }); + if ('representations' in variables) { + throw new Error(`Variables cannot contain key "representations"`); + } + const dataReceivedFromService = await sendOperation( context, operationForEntitiesFetch(fetch), - { representations }, + { ...variables, representations }, ); if (!dataReceivedFromService) {