Skip to content

Commit ab94135

Browse files
authored
Merge pull request #4175 from apollographql/release-2.14.1
2 parents 68a21f9 + 2da65ef commit ab94135

File tree

21 files changed

+154
-43
lines changed

21 files changed

+154
-43
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ The version headers in this history reflect the versions of Apollo Server itself
1111
1212
- _Nothing yet! Stay tuned!_
1313

14+
### v2.14.1
15+
16+
- `apollo-server-testing`: Ensure that user-provided context is cloned when using `createTestClient`, per the instructions in the [intergration testing]() section of the Apollo Server documentation. [Issue #4170](https://github.com/apollographql/apollo-server/issues/4170) [PR #TODO](https://github.com/apollographql/apollo-server/pull/TODO)
17+
1418
### v2.14.0
1519

1620
- `apollo-server-core` / `apollo-server-plugin-base`: Add support for `willResolveField` and corresponding end-handler within `executionDidStart`. This brings the remaining bit of functionality that was previously only available from `graphql-extensions` to the new plugin API. The `graphql-extensions` API (which was never documented) will be deprecated in Apollo Server 3.x. To see the documentation for the request pipeline API, see [its documentation](https://www.apollographql.com/docs/apollo-server/integrations/plugins/). For more details, see the attached PR. [PR #3988](https://github.com/apollographql/apollo-server/pull/3988)

packages/apollo-federation/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
77
- _Nothing yet! Stay tuned._
88

9+
## 0.16.2
10+
11+
- Only changes in the similarly versioned `@apollo/gateway` package.
12+
913
## 0.16.1
1014

1115
- Only changes in the similarly versioned `@apollo/gateway` package.

packages/apollo-federation/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@apollo/federation",
3-
"version": "0.16.1",
3+
"version": "0.16.2",
44
"description": "Apollo Federation Utilities",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-gateway/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
77
- __FIX__: Collapse nested required fields into a single body in the query plan. Before, some nested fields' selection sets were getting split, causing some of their subfields to be dropped when executing the query. This fix collapses the split selection sets into one. [#4064](https://github.com/apollographql/apollo-server/pull/4064)
88

9+
## 0.16.2
10+
11+
- __FIX__: Collapse nested required fields into a single body in the query plan. Before, some nested fields' selection sets were getting split, causing some of their subfields to be dropped when executing the query. This fix collapses the split selection sets into one. [#4064](https://github.com/apollographql/apollo-server/pull/4064)
12+
913
## 0.16.1
1014

1115
- __NEW__: Provide the ability to pass a custom `fetcher` during `RemoteGraphQLDataSource` construction to be used when executing operations against downstream services. Providing a custom `fetcher` may be necessary to accommodate more advanced needs, e.g., configuring custom TLS certificates for internal services. [PR #4149](https://github.com/apollographql/apollo-server/pull/4149)

packages/apollo-gateway/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@apollo/gateway",
3-
"version": "0.16.1",
3+
"version": "0.16.2",
44
"description": "Apollo Gateway",
55
"author": "[email protected]",
66
"main": "dist/index.js",

packages/apollo-server-azure-functions/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-azure-functions",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Azure Functions",
55
"keywords": [
66
"GraphQL",

packages/apollo-server-cloud-functions/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-cloud-functions",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Google Cloud Functions",
55
"keywords": [
66
"GraphQL",

packages/apollo-server-cloudflare/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-cloudflare",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Cloudflare workers",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server-core/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-core",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Core engine for Apollo GraphQL server",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server-core/src/ApolloServer.ts

+10
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ import {
7878
CacheControlExtensionOptions,
7979
} from 'apollo-cache-control';
8080
import { getEngineApiKey, getEngineGraphVariant } from "apollo-engine-reporting/dist/agent";
81+
import { cloneObject } from "./runHttpQuery";
8182

8283
const NoIntrospection = (context: ValidationContext) => ({
8384
Field(node: FieldDefinitionNode) {
@@ -855,8 +856,17 @@ export class ApolloServerBase {
855856

856857
if (typeof options.context === 'function') {
857858
options.context = (options.context as () => never)();
859+
} else if (typeof options.context === 'object') {
860+
// FIXME: We currently shallow clone the context for every request,
861+
// but that's unlikely to be what people want.
862+
// We allow passing in a function for `context` to ApolloServer,
863+
// but this only runs once for a batched request (because this is resolved
864+
// in ApolloServer#graphQLServerOptions, before runHttpQuery is invoked).
865+
// NOTE: THIS IS DUPLICATED IN runHttpQuery.ts' buildRequestContext.
866+
options.context = cloneObject(options.context);
858867
}
859868

869+
860870
const requestCtx: GraphQLRequestContext = {
861871
logger: this.logger,
862872
schema: options.schema,

packages/apollo-server-core/src/runHttpQuery.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ export async function processHTTPRequest<TContext>(
246246
// We allow passing in a function for `context` to ApolloServer,
247247
// but this only runs once for a batched request (because this is resolved
248248
// in ApolloServer#graphQLServerOptions, before runHttpQuery is invoked).
249+
// NOTE: THIS IS DUPLICATED IN ApolloServerBase.prototype.executeOperation.
249250
const context = cloneObject(options.context);
250251
return {
251252
// While `logger` is guaranteed by internal Apollo Server usage of
@@ -458,6 +459,6 @@ function prettyJSONStringify(value: any) {
458459
return JSON.stringify(value) + '\n';
459460
}
460461

461-
function cloneObject<T extends Object>(object: T): T {
462+
export function cloneObject<T extends Object>(object: T): T {
462463
return Object.assign(Object.create(Object.getPrototypeOf(object)), object);
463464
}

packages/apollo-server-express/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-express",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Express and Connect",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server-fastify/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-fastify",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Fastify",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server-hapi/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-hapi",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Hapi",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server-integration-testsuite/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "apollo-server-integration-testsuite",
33
"private": true,
4-
"version": "2.14.0",
4+
"version": "2.14.1",
55
"description": "Apollo Server Integrations testsuite",
66
"main": "dist/index.js",
77
"types": "dist/index.d.ts",

packages/apollo-server-integration-testsuite/src/ApolloServer.ts

+115-27
Original file line numberDiff line numberDiff line change
@@ -566,11 +566,13 @@ export function testApolloServer<AS extends ApolloServerBase>(
566566
describe('Plugins', () => {
567567
let apolloFetch: ApolloFetch;
568568
let apolloFetchResponse: ParsedResponse;
569+
let serverInstance: ApolloServerBase;
569570

570571
const setupApolloServerAndFetchPairForPlugins = async (
571572
plugins: PluginDefinition[] = [],
572573
) => {
573-
const { url: uri } = await createApolloServer({
574+
const { url: uri, server } = await createApolloServer({
575+
context: { customContext: true },
574576
typeDefs: gql`
575577
type Query {
576578
justAField: String
@@ -579,6 +581,8 @@ export function testApolloServer<AS extends ApolloServerBase>(
579581
plugins,
580582
});
581583

584+
serverInstance = server;
585+
582586
apolloFetch = createApolloFetch({ uri })
583587
// Store the response so we can inspect it.
584588
.useAfter(({ response }, next) => {
@@ -587,6 +591,56 @@ export function testApolloServer<AS extends ApolloServerBase>(
587591
});
588592
};
589593

594+
// Test for https://github.com/apollographql/apollo-server/issues/4170
595+
it('works when using executeOperation', async () => {
596+
const encounteredFields = [];
597+
const encounteredContext = [];
598+
await setupApolloServerAndFetchPairForPlugins([
599+
{
600+
requestDidStart: () => ({
601+
executionDidStart: () => ({
602+
willResolveField({ info, context }) {
603+
encounteredFields.push(info.path);
604+
encounteredContext.push(context);
605+
},
606+
}),
607+
}),
608+
},
609+
]);
610+
611+
// The bug in 4170 (linked above) was occurring because of a failure
612+
// to clone context in `executeOperation` in the same way that occurs
613+
// in `runHttpQuery` prior to entering the request pipeline. That
614+
// resulted in the inability to attach a symbol to the context because
615+
// the symbol already existed on the context. Of course, a context
616+
// is only created after the first invocation, so we'll run this twice
617+
// to encounter the error where it was in the way when we tried to set
618+
// it the second time. While we could have tested for the property
619+
// before assigning to it, that is not the contract we have with the
620+
// context, which should have been copied on `executeOperation` (which
621+
// is meant to be used by testing, currently).
622+
await serverInstance.executeOperation({
623+
query: '{ justAField }',
624+
});
625+
await serverInstance.executeOperation({
626+
query: '{ justAField }',
627+
});
628+
629+
expect(encounteredFields).toStrictEqual([
630+
{ key: 'justAField', prev: undefined },
631+
{ key: 'justAField', prev: undefined },
632+
]);
633+
634+
// This bit is just to ensure that nobody removes `context` from the
635+
// `setupApolloServerAndFetchPairForPlugins` thinking it's unimportant.
636+
// When a custom context is not provided, a new one is initialized
637+
// on each request.
638+
expect(encounteredContext).toStrictEqual([
639+
expect.objectContaining({customContext: true}),
640+
expect.objectContaining({customContext: true}),
641+
]);
642+
});
643+
590644
it('returns correct status code for a normal operation', async () => {
591645
await setupApolloServerAndFetchPairForPlugins();
592646

@@ -1492,37 +1546,71 @@ export function testApolloServer<AS extends ApolloServerBase>(
14921546
expect(spy).toHaveBeenCalledTimes(2);
14931547
});
14941548

1495-
it('clones the context for every request', async () => {
1496-
const uniqueContext = { key: 'major' };
1497-
const spy = jest.fn(() => 'hi');
1498-
const typeDefs = gql`
1499-
type Query {
1500-
hello: String
1501-
}
1502-
`;
1503-
const resolvers = {
1504-
Query: {
1505-
hello: (_parent: any, _args: any, context: any) => {
1506-
expect(context.key).toEqual('major');
1507-
context.key = 'minor';
1508-
return spy();
1549+
describe('context cloning', () => {
1550+
it('clones the context for request pipeline requests', async () => {
1551+
const uniqueContext = { key: 'major' };
1552+
const spy = jest.fn(() => 'hi');
1553+
const typeDefs = gql`
1554+
type Query {
1555+
hello: String
1556+
}
1557+
`;
1558+
const resolvers = {
1559+
Query: {
1560+
hello: (_parent: any, _args: any, context: any) => {
1561+
expect(context.key).toEqual('major');
1562+
context.key = 'minor';
1563+
return spy();
1564+
},
15091565
},
1510-
},
1511-
};
1512-
const { url: uri } = await createApolloServer({
1513-
typeDefs,
1514-
resolvers,
1515-
context: uniqueContext,
1566+
};
1567+
const { url: uri } = await createApolloServer({
1568+
typeDefs,
1569+
resolvers,
1570+
context: uniqueContext,
1571+
});
1572+
1573+
const apolloFetch = createApolloFetch({ uri });
1574+
1575+
expect(spy).not.toBeCalled();
1576+
1577+
await apolloFetch({ query: '{hello}' });
1578+
expect(spy).toHaveBeenCalledTimes(1);
1579+
await apolloFetch({ query: '{hello}' });
1580+
expect(spy).toHaveBeenCalledTimes(2);
15161581
});
15171582

1518-
const apolloFetch = createApolloFetch({ uri });
1583+
// https://github.com/apollographql/apollo-server/issues/4170
1584+
it('for every request with executeOperation', async () => {
1585+
const uniqueContext = { key: 'major' };
1586+
const spy = jest.fn(() => 'hi');
1587+
const typeDefs = gql`
1588+
type Query {
1589+
hello: String
1590+
}
1591+
`;
1592+
const resolvers = {
1593+
Query: {
1594+
hello: (_parent: any, _args: any, context: any) => {
1595+
expect(context.key).toEqual('major');
1596+
context.key = 'minor';
1597+
return spy();
1598+
},
1599+
},
1600+
};
1601+
const { server } = await createApolloServer({
1602+
typeDefs,
1603+
resolvers,
1604+
context: uniqueContext,
1605+
});
15191606

1520-
expect(spy).not.toBeCalled();
1607+
expect(spy).not.toBeCalled();
15211608

1522-
await apolloFetch({ query: '{hello}' });
1523-
expect(spy).toHaveBeenCalledTimes(1);
1524-
await apolloFetch({ query: '{hello}' });
1525-
expect(spy).toHaveBeenCalledTimes(2);
1609+
await server.executeOperation({ query: '{hello}' });
1610+
expect(spy).toHaveBeenCalledTimes(1);
1611+
await server.executeOperation({ query: '{hello}' });
1612+
expect(spy).toHaveBeenCalledTimes(2);
1613+
});
15261614
});
15271615

15281616
describe('as a function', () => {

packages/apollo-server-koa/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-koa",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Koa",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server-lambda/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-lambda",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for AWS Lambda",
55
"keywords": [
66
"GraphQL",

packages/apollo-server-micro/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-micro",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production-ready Node.js GraphQL server for Micro",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server-testing/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server-testing",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Test utils for apollo-server",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

packages/apollo-server/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apollo-server",
3-
"version": "2.14.0",
3+
"version": "2.14.1",
44
"description": "Production ready GraphQL Server",
55
"author": "[email protected]",
66
"main": "dist/index.js",

0 commit comments

Comments
 (0)