From 2b0ad41eb15c49dca9ab42be85be297ef0a7343a Mon Sep 17 00:00:00 2001 From: Benedict Hobart Date: Wed, 29 Nov 2017 10:07:51 +1100 Subject: [PATCH 1/4] fix: remove shallow cloning of object when executing a batch http request --- packages/apollo-server-core/src/runHttpQuery.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/apollo-server-core/src/runHttpQuery.ts b/packages/apollo-server-core/src/runHttpQuery.ts index df156784c99..50491a5a5c6 100644 --- a/packages/apollo-server-core/src/runHttpQuery.ts +++ b/packages/apollo-server-core/src/runHttpQuery.ts @@ -97,19 +97,11 @@ export async function runHttpQuery(handlerArguments: Array, request: HttpQu } } - // Shallow clone context for queries in batches. This allows - // users to distinguish multiple queries in the batch and to - // modify the context object without interfering with each other. - let context = optionsObject.context; - if (isBatch) { - context = Object.assign({}, context || {}); - } - let params = { schema: optionsObject.schema, query: query, variables: variables, - context: context, + context: optionsObject.context, rootValue: optionsObject.rootValue, operationName: operationName, logFunction: optionsObject.logFunction, From 9a771cc84ef969dcbae8626e9c20bbdf0dd3cb0f Mon Sep 17 00:00:00 2001 From: Benedict Hobart Date: Wed, 29 Nov 2017 10:54:35 +1100 Subject: [PATCH 2/4] chore: update tests, document changes in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c1a6750868..571b66265f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Include readme for npm packages * Update peerDependencies version for micro [PR #671](https://github.com/apollographql/apollo-server/pull/671) * Corrected the hapi example both in the README.md [PR #689] [Issue #689] +* Remove context cloning when batching[PR #679](https://github.com/apollographql/apollo-server/pull/679) ### v1.1.6 * Fixes bug where CORS would not allow `Access-Control-Allow-Origin: *` with credential 'include', changed to 'same-origin' [Issue #514](https://github.com/apollographql/apollo-server/issues/514) From 32e4bda72c2d3621a56244d163f9bfc066b982a7 Mon Sep 17 00:00:00 2001 From: Benedict Hobart Date: Fri, 8 Dec 2017 16:00:38 +1100 Subject: [PATCH 3/4] fix: add back shallow cloning, update options to accept context as a function --- CHANGELOG.md | 2 +- .../apollo-server-core/src/runHttpQuery.ts | 13 ++++++- .../src/index.ts | 35 +++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 571b66265f6..46073d97e28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ * Include readme for npm packages * Update peerDependencies version for micro [PR #671](https://github.com/apollographql/apollo-server/pull/671) * Corrected the hapi example both in the README.md [PR #689] [Issue #689] -* Remove context cloning when batching[PR #679](https://github.com/apollographql/apollo-server/pull/679) +* Change GraphqlOptions to also accept context as a function[PR #679](https://github.com/apollographql/apollo-server/pull/679) ### v1.1.6 * Fixes bug where CORS would not allow `Access-Control-Allow-Origin: *` with credential 'include', changed to 'same-origin' [Issue #514](https://github.com/apollographql/apollo-server/issues/514) diff --git a/packages/apollo-server-core/src/runHttpQuery.ts b/packages/apollo-server-core/src/runHttpQuery.ts index 50491a5a5c6..7bc490cd087 100644 --- a/packages/apollo-server-core/src/runHttpQuery.ts +++ b/packages/apollo-server-core/src/runHttpQuery.ts @@ -27,6 +27,10 @@ function isQueryOperation(query: DocumentNode, operationName: string) { return operationAST.operation === 'query'; } +export function isFunction(arg: any): arg is Function { + return typeof arg === 'function'; +} + export async function runHttpQuery(handlerArguments: Array, request: HttpQueryRequest): Promise { let isGetRequest: boolean = false; let optionsObject: GraphQLOptions; @@ -97,11 +101,18 @@ export async function runHttpQuery(handlerArguments: Array, request: HttpQu } } + let context = optionsObject.context; + if (isFunction(context)) { + context = context(); + } else if (isBatch) { + context = Object.assign({}, context || {}); + } + let params = { schema: optionsObject.schema, query: query, variables: variables, - context: optionsObject.context, + context, rootValue: optionsObject.rootValue, operationName: operationName, logFunction: optionsObject.logFunction, diff --git a/packages/apollo-server-integration-testsuite/src/index.ts b/packages/apollo-server-integration-testsuite/src/index.ts index 8567e580c02..69c58604c79 100644 --- a/packages/apollo-server-integration-testsuite/src/index.ts +++ b/packages/apollo-server-integration-testsuite/src/index.ts @@ -522,6 +522,41 @@ export default (createApp: CreateAppFunc, destroyApp?: DestroyAppFunc) => { }); }); + it('executes batch context if it is a function', () => { + let callCount = 0; + app = createApp({graphqlOptions: { + schema, + context: () => { + callCount++; + return ({testField: 'expected'}); + }, + }}); + const expected = [ + { + data: { + testContext: 'expected', + }, + }, + { + data: { + testContext: 'expected', + }, + }, + ]; + const req = request(app) + .post('/graphql') + .send([{ + query: 'query test{ testContext }', + }, { + query: 'query test{ testContext }', + }]); + return req.then((res) => { + expect(callCount).to.equal(2); + expect(res.status).to.equal(200); + return expect(res.body).to.deep.equal(expected); + }); + }); + it('can handle a request with a mutation', async () => { app = await createApp(); const expected = { From 38de8c46ba88734ae7abfe685c6382719f7ab942 Mon Sep 17 00:00:00 2001 From: Benedict Hobart Date: Mon, 11 Dec 2017 09:12:27 +1100 Subject: [PATCH 4/4] fix: add cloning of context prototype for batch queries --- packages/apollo-server-core/src/runHttpQuery.ts | 6 +++--- packages/apollo-server-integration-testsuite/src/index.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/apollo-server-core/src/runHttpQuery.ts b/packages/apollo-server-core/src/runHttpQuery.ts index 7bc490cd087..0990161005b 100644 --- a/packages/apollo-server-core/src/runHttpQuery.ts +++ b/packages/apollo-server-core/src/runHttpQuery.ts @@ -27,7 +27,7 @@ function isQueryOperation(query: DocumentNode, operationName: string) { return operationAST.operation === 'query'; } -export function isFunction(arg: any): arg is Function { +function isFunction(arg: any): arg is Function { return typeof arg === 'function'; } @@ -101,11 +101,11 @@ export async function runHttpQuery(handlerArguments: Array, request: HttpQu } } - let context = optionsObject.context; + let context = optionsObject.context || {}; if (isFunction(context)) { context = context(); } else if (isBatch) { - context = Object.assign({}, context || {}); + context = Object.assign(Object.create(Object.getPrototypeOf(context)), context); } let params = { diff --git a/packages/apollo-server-integration-testsuite/src/index.ts b/packages/apollo-server-integration-testsuite/src/index.ts index 69c58604c79..d4731bea28c 100644 --- a/packages/apollo-server-integration-testsuite/src/index.ts +++ b/packages/apollo-server-integration-testsuite/src/index.ts @@ -522,9 +522,9 @@ export default (createApp: CreateAppFunc, destroyApp?: DestroyAppFunc) => { }); }); - it('executes batch context if it is a function', () => { + it('executes batch context if it is a function', async () => { let callCount = 0; - app = createApp({graphqlOptions: { + app = await createApp({graphqlOptions: { schema, context: () => { callCount++;