diff --git a/docs/source/integrations/plugins.md b/docs/source/integrations/plugins.md index da9d5794251..b6d1525901a 100644 --- a/docs/source/integrations/plugins.md +++ b/docs/source/integrations/plugins.md @@ -114,6 +114,54 @@ defines functions that respond to request lifecycle events. This structure organizes and encapsulates all of your plugin's request lifecycle logic, making it easier to reason about. +The following request lifecycle event handlers can optionally return a function +that will be invoked after the lifecycle phase is complete: + +* [`parsingDidStart`](#parsingdidstart) +* [`validationDidStart`](#validationdidstart) +* [`executionDidStart`](#executiondidstart) + +These "end hooks" will be invoked with any error(s) that occurred during the +execution of that lifecycle phase. For example, the following plugin will log +any errors that occur during any of the above lifecycle events: + +```js +const myPlugin = { + requestDidStart() { + return { + parsingDidStart() { + return (err) => { + if (err) { + console.error(err); + } + } + }, + validationDidStart() { + // This end hook is unique in that it can receive an array of errors, + // which will contain every validation error that occurred + return (errs) => { + if (errs) { + errs.forEach(err => console.error(err)); + } + } + }, + executionDidStart() { + return (err) => { + if (err) { + console.error(err); + } + } + } + } + } +} +``` + +Note that the `validationDidStart` end hook receives an array of errors, which +will contain every validation error that occurred, if any. The arguments to each +end hook are documented in the type definitions in the [request lifecycle events +docs](#request-lifecycle-events) below. + ### Inspecting request and response details As the example above shows, `requestDidStart` and request lifecycle functions accept a `requestContext` @@ -287,6 +335,22 @@ didResolveOperation?( ): ValueOrPromise; ``` +### `responseForOperation` + +The `responseForOperation` event is fired immediately before GraphQL execution +would take place. If its return value resolves to a non-null `GraphQLResponse`, +that result is used instead of executing the query. Hooks from different plugins +are invoked in series and the first non-null response is used. + +```typescript +responseForOperation?( + requestContext: WithRequired< + GraphQLRequestContext, + 'metrics' | 'source' | 'document' | 'operationName' | 'operation' + >, +): ValueOrPromise; +``` + ### `executionDidStart` The `executionDidStart` event fires whenever Apollo Server begins executing the