Skip to content

Commit

Permalink
feat: [server] Add new hook
Browse files Browse the repository at this point in the history
  • Loading branch information
EmrysMyrddin committed Feb 5, 2025
1 parent ba5f1fb commit 9c889ed
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 10 deletions.
26 changes: 26 additions & 0 deletions packages/graphql-yoga/src/plugins/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export type Plugin<
* should be used for sending the result over the wire.
*/
onResultProcess?: OnResultProcess<TServerContext>;
/**
* This hook is invoked for each graphql operation.
* Here you can set graphql operation handler.
*/
onOperation?: OnOperationHook<TServerContext>;
};

export type OnYogaInitHook<TServerContext extends Record<string, any>> = (
Expand Down Expand Up @@ -203,3 +208,24 @@ export type OnPluginInitEventPayload<PluginContext extends Record<string, any>>
export type OnPluginInitHook<ContextType extends Record<string, any>> = (
options: OnPluginInitEventPayload<ContextType>,
) => void;

export type OperationHandler<TServerContext extends Record<string, any>> = (payload: {
params: GraphQLParams;
request: Request;
context: TServerContext;
}) => PromiseOrValue<ExecutionResult | AsyncIterable<ExecutionResult> | undefined>;

export type OnOperationHookPayload<TServerContext extends Record<string, any>> = {
context: TServerContext;
operationHandler: OperationHandler<TServerContext>;
setOperationHandler: (operationHandler: OperationHandler<TServerContext>) => void;
params: GraphQLParams;
request: Request;
};

/**
* Invoked for each GraphQL operation.
*/
export type OnOperationHook<TServerContext extends Record<string, any>> = (
payload: OnOperationHookPayload<TServerContext>,
) => PromiseOrValue<void>;
45 changes: 35 additions & 10 deletions packages/graphql-yoga/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import {
Plugin,
RequestParser,
ResultProcessorInput,
type OnOperationHook,
type OperationHandler,
} from './plugins/types.js';
import { GraphiQLOptions, GraphiQLOptionsOrFactory, useGraphiQL } from './plugins/use-graphiql.js';
import { useHealthCheck } from './plugins/use-health-check.js';
Expand Down Expand Up @@ -217,6 +219,7 @@ export class YogaServer<
>;
private onRequestParseHooks: OnRequestParseHook<TServerContext>[];
private onParamsHooks: OnParamsHook<TServerContext>[];
private onOperationHooks: OnOperationHook<TServerContext>[];
private onExecutionResultHooks: OnExecutionResultHook<TServerContext>[];
private onResultProcessHooks: OnResultProcess<TServerContext>[];
private maskedErrorsOpts: YogaMaskedErrorOpts | null;
Expand Down Expand Up @@ -437,6 +440,7 @@ export class YogaServer<

this.onRequestParseHooks = [];
this.onParamsHooks = [];
this.onOperationHooks = [];
this.onExecutionResultHooks = [];
this.onResultProcessHooks = [];
for (const plugin of this.plugins) {
Expand All @@ -452,6 +456,9 @@ export class YogaServer<
if (plugin.onParams) {
this.onParamsHooks.push(plugin.onParams);
}
if (plugin.onOperation) {
this.onOperationHooks.push(plugin.onOperation);
}
if (plugin.onExecutionResult) {
this.onExecutionResultHooks.push(plugin.onExecutionResult);
}
Expand All @@ -462,16 +469,7 @@ export class YogaServer<
}
}

async getResultForParams(
{
params,
request,
}: {
params: GraphQLParams;
request: Request;
},
context: TServerContext,
) {
handleOperation: OperationHandler<TServerContext> = async ({ params, request, context }) => {
let result: ExecutionResult | AsyncIterable<ExecutionResult> | undefined;

try {
Expand Down Expand Up @@ -552,6 +550,33 @@ export class YogaServer<
});
}
return result;
};

async getResultForParams(
{
params,
request,
}: {
params: GraphQLParams;
request: Request;
},
context: TServerContext,
) {
let operationHandler = this.handleOperation;

for (const onOperationHook of this.onOperationHooks) {
await onOperationHook({
operationHandler,
setOperationHandler: newOperationHandler => {
operationHandler = newOperationHandler;
},
context,
params,
request,
});
}

return operationHandler({ params, request, context });
}

handle: ServerAdapterRequestHandler<TServerContext> = async (
Expand Down

0 comments on commit 9c889ed

Please sign in to comment.