Skip to content

Commit

Permalink
Fix shallow cloning of context when executing a batch request (#679)
Browse files Browse the repository at this point in the history
This fixes the default behavior for class-based contexts by also cloning the prototype, and it allows you to customize per-operation behavior by passing in a function as context.
  • Loading branch information
bennyhobart authored and martijnwalraven committed Dec 12, 2017
1 parent 7b6efff commit 62c397e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
* 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)
Expand Down
17 changes: 10 additions & 7 deletions packages/apollo-server-core/src/runHttpQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ function isQueryOperation(query: DocumentNode, operationName: string) {
return operationAST.operation === 'query';
}

function isFunction(arg: any): arg is Function {
return typeof arg === 'function';
}

export async function runHttpQuery(handlerArguments: Array<any>, request: HttpQueryRequest): Promise<string> {
let isGetRequest: boolean = false;
let optionsObject: GraphQLOptions;
Expand Down Expand Up @@ -97,19 +101,18 @@ export async function runHttpQuery(handlerArguments: Array<any>, 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 context = optionsObject.context || {};
if (isFunction(context)) {
context = context();
} else if (isBatch) {
context = Object.assign(Object.create(Object.getPrototypeOf(context)), context);
}

let params = {
schema: optionsObject.schema,
query: query,
variables: variables,
context: context,
context,
rootValue: optionsObject.rootValue,
operationName: operationName,
logFunction: optionsObject.logFunction,
Expand Down
35 changes: 35 additions & 0 deletions packages/apollo-server-integration-testsuite/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,41 @@ export default (createApp: CreateAppFunc, destroyApp?: DestroyAppFunc) => {
});
});

it('executes batch context if it is a function', async () => {
let callCount = 0;
app = await 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 = {
Expand Down

0 comments on commit 62c397e

Please sign in to comment.