From 3c18fafa385b10b17f614f6993496fb1d1d17dc5 Mon Sep 17 00:00:00 2001 From: Benedict Hobart Date: Fri, 8 Dec 2017 16:00:38 +1100 Subject: [PATCH] fix: add back shallow cloning, update options to accept context as a function --- CHANGELOG.md | 1 + .../apollo-server-core/src/runHttpQuery.ts | 13 +++- .../src/index.ts | 71 ++++++++++++++++++- 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae6b7ed9c3f..24dbbbb8ee8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Include readme for npm packages * Remove context cloning when batching[PR #679](https://github.com/apollographql/apollo-server/pull/679) * Update peerDependencies version for micro [PR #671](https://github.com/apollographql/apollo-server/pull/671) +* 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 672f6ad500c..b1d9cd051cf 100644 --- a/packages/apollo-server-integration-testsuite/src/index.ts +++ b/packages/apollo-server-integration-testsuite/src/index.ts @@ -43,7 +43,11 @@ const queryType = new GraphQLObjectType({ testContext: { type: GraphQLString, resolve(_, args, context) { - return context.testField; + if (context.otherField) { + return 'unexpected'; + } + context.otherField = true; + return context.testField; }, }, testRootValue: { @@ -487,6 +491,71 @@ export default (createApp: CreateAppFunc, destroyApp?: DestroyAppFunc) => { }); }); + it('clones batch context', () => { + app = createApp({graphqlOptions: { + schema, + context: {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(res.status).to.equal(200); + return expect(res.body).to.deep.equal(expected); + }); + }); + + 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', () => { app = createApp(); const expected = {