Skip to content

Commit

Permalink
Pass the context request and response extension methods (#1547)
Browse files Browse the repository at this point in the history
* Pass the context along to all the extension methods

Addresses #1343

With this change you should now be able to implement an extension like so:

```javascript
class MyErrorTrackingExtension extends GraphQLExtension {
    willSendResponse(o) {
        const { context, graphqlResponse } = o

        context.trackErrors(graphqlResponse.errors)

        return o
    }
}
```

Edit by @evans :
fixes #1343
fixes #614 as the request object can be taken from context or from requestDidStart
fixes #631 ""

* Remove context from extra extension functions

The context shouldn't be necessary for format, parse, validation, and
execute. Format generally outputs the state of the extension. Parse and
validate don't depend on the context. Execution includes the context
argument as contextValue

* Move change entry under vNext
  • Loading branch information
Whoaa512 authored and abernix committed Oct 10, 2018
1 parent e4d672c commit 84bc834
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 12 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

### vNEXT

- FIXME(@abernix): Allow context to be passed to all GraphQLExtension methods.
- Allow an optional function to resolve the `rootValue`, passing the `DocumentNode` AST to determine the value. [PR #1555](https://github.com/apollographql/apollo-server/pull/1555)
- Follow-up on the work in [PR #1516](https://github.com/apollographql/apollo-server/pull/1516) to also fix missing insertion cursor/caret when a custom GraphQL configuration is specified which doesn't specify its own `cursorShape` property. [PR #1607](https://github.com/apollographql/apollo-server/pull/1607)

Expand Down
4 changes: 2 additions & 2 deletions packages/apollo-engine-reporting/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class EngineReportingExtension<TContext = any>
request: Request;
queryString?: string;
parsedQuery?: DocumentNode;
variables: Record<string, any>;
variables?: Record<string, any>;
persistedQueryHit?: boolean;
persistedQueryRegister?: boolean;
context: any;
Expand Down Expand Up @@ -153,7 +153,7 @@ export class EngineReportingExtension<TContext = any>
} else {
try {
this.trace.details!.variablesJson![name] = JSON.stringify(
o.variables[name],
o.variables![name],
);
} catch (e) {
// This probably means that the value contains a circular reference,
Expand Down
22 changes: 22 additions & 0 deletions packages/apollo-server-core/src/__tests__/runQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,28 @@ describe('runQuery', () => {
});
});
});

it('runs willSendResponse with extensions context', async () => {
class CustomExtension implements GraphQLExtension<any> {
willSendResponse(o: any) {
expect(o).toHaveProperty('context.baz', 'always here');
return o;
}
}

const queryString = `{ testString }`;
const expected = { testString: 'it works' };
const extensions = [() => new CustomExtension()];
return runQuery({
schema,
queryString,
context: { baz: 'always here' },
extensions,
request: new MockReq(),
}).then(res => {
expect(res.data).toEqual(expected);
});
});
});

describe('async_hooks', () => {
Expand Down
6 changes: 4 additions & 2 deletions packages/apollo-server-core/src/formatters.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GraphQLExtension, GraphQLResponse } from 'graphql-extensions';
import { formatApolloErrors } from 'apollo-server-errors';

export class FormatErrorExtension extends GraphQLExtension {
export class FormatErrorExtension<TContext = any> extends GraphQLExtension {
private formatError?: Function;
private debug: boolean;

Expand All @@ -13,9 +13,11 @@ export class FormatErrorExtension extends GraphQLExtension {

public willSendResponse(o: {
graphqlResponse: GraphQLResponse;
}): void | { graphqlResponse: GraphQLResponse } {
context: TContext;
}): void | { graphqlResponse: GraphQLResponse; context: TContext } {
if (o.graphqlResponse.errors) {
return {
...o,
graphqlResponse: {
...o.graphqlResponse,
errors: formatApolloErrors(o.graphqlResponse.errors, {
Expand Down
14 changes: 10 additions & 4 deletions packages/apollo-server-integration-testsuite/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,11 @@ export function testApolloServer<AS extends ApolloServerBase>(
}
});

class Extension extends GraphQLExtension {
willSendResponse(o: { graphqlResponse: GraphQLResponse }) {
class Extension<TContext = any> extends GraphQLExtension {
willSendResponse(o: {
graphqlResponse: GraphQLResponse;
context: TContext;
}) {
expect(o.graphqlResponse.errors.length).toEqual(1);
// formatError should be called after extensions
expect(formatError).not.toBeCalled();
Expand Down Expand Up @@ -636,8 +639,11 @@ export function testApolloServer<AS extends ApolloServerBase>(
return error;
});

class Extension extends GraphQLExtension {
willSendResponse(_o: { graphqlResponse: GraphQLResponse }) {
class Extension<TContext = any> extends GraphQLExtension {
willSendResponse(_o: {
graphqlResponse: GraphQLResponse;
context: TContext;
}) {
// formatError should be called after extensions
expect(formatError).not.toBeCalled();
extension();
Expand Down
9 changes: 6 additions & 3 deletions packages/graphql-extensions/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class GraphQLExtension<TContext = any> {
variables?: { [key: string]: any };
persistedQueryHit?: boolean;
persistedQueryRegister?: boolean;
context: TContext;
}): EndHandler | void;
public parsingDidStart?(o: { queryString: string }): EndHandler | void;
public validationDidStart?(): EndHandler | void;
Expand All @@ -42,7 +43,8 @@ export class GraphQLExtension<TContext = any> {

public willSendResponse?(o: {
graphqlResponse: GraphQLResponse;
}): void | { graphqlResponse: GraphQLResponse };
context: TContext;
}): void | { graphqlResponse: GraphQLResponse; context: TContext };

public willResolveField?(
source: any,
Expand Down Expand Up @@ -71,7 +73,7 @@ export class GraphQLExtensionStack<TContext = any> {
variables?: { [key: string]: any };
persistedQueryHit?: boolean;
persistedQueryRegister?: boolean;
extensions?: Record<string, any>;
context: TContext;
}): EndHandler {
return this.handleDidStart(
ext => ext.requestDidStart && ext.requestDidStart(o),
Expand All @@ -98,7 +100,8 @@ export class GraphQLExtensionStack<TContext = any> {

public willSendResponse(o: {
graphqlResponse: GraphQLResponse;
}): { graphqlResponse: GraphQLResponse } {
context: TContext;
}): { graphqlResponse: GraphQLResponse; context: TContext } {
let reference = o;
// Reverse the array, since this is functions as an end handler
[...this.extensions].reverse().forEach(extension => {
Expand Down

0 comments on commit 84bc834

Please sign in to comment.