import type { ApolloServerPlugin } from "@apollo/server"; import { getComplexity, simpleEstimator } from "graphql-query-complexity"; import { GraphQLError } from "graphql"; interface QueryComplexityPluginOptions { maxComplexity?: number; defaultComplexity?: number; } /** * Apollo Server Plugin für Query Complexity Limits * Verhindert zu komplexe Queries, die das System überlasten könnten */ export const queryComplexityPlugin = ( options: QueryComplexityPluginOptions = {} ): ApolloServerPlugin => { const maxComplexity = options.maxComplexity ?? 1000; const defaultComplexity = options.defaultComplexity ?? 1; return { async requestDidStart() { return { async didResolveOperation({ request, document, schema }) { if (!schema) return; try { const complexity = getComplexity({ schema, operationName: request.operationName || undefined, query: document, variables: request.variables || {}, estimators: [ // Basis-Komplexität für jeden Field simpleEstimator({ defaultComplexity }), ], }); // Speichere Complexity im Request für Monitoring (request as any).complexity = complexity; if (complexity > maxComplexity) { throw new GraphQLError( `Query zu komplex (${complexity}). Maximum: ${maxComplexity}`, { extensions: { code: "QUERY_TOO_COMPLEX", complexity, maxComplexity, }, } ); } } catch (error: any) { // Wenn es ein Schema-Realm-Problem gibt, logge es aber blockiere nicht if (error.message?.includes("another module or realm")) { console.warn( "[Query Complexity] Schema-Realm-Konflikt, Complexity-Check übersprungen" ); return; } throw error; } }, }; }, }; };