UNPKG

@graphql-yoga/apollo-managed-federation

Version:

This plugin integrates Apollo Managed Federation into Yoga.

66 lines (65 loc) 3.18 kB
import { createGraphQLError } from 'graphql-yoga'; import { SupergraphSchemaManager, } from '@graphql-tools/federation'; export function useManagedFederation(options = {}) { let _supergraphManager; function ensureSupergraphManager() { if (_supergraphManager == null) { if (options instanceof SupergraphSchemaManager) { _supergraphManager = options; } else { _supergraphManager = new SupergraphSchemaManager(options); } } return _supergraphManager; } const plugin = { onYogaInit({ yoga }) { ensureSupergraphManager().addEventListener('log', ({ detail: { level, message, source } }) => { yoga.logger[level](`[ManagedFederation]${source === 'uplink' ? ' <UPLINK>' : ''} ${message}`); }); ensureSupergraphManager().addEventListener('failure', ({ detail: { error, delayInSeconds } }) => { if (options.onFailure) { return options.onFailure(error, delayInSeconds); } const message = error?.message ?? error; yoga.logger.error(`[ManagedFederation] Failed to load supergraph schema.${message ? ` Last error: ${message}` : ''}`); yoga.logger.info(`[ManagedFederation] No failure handler provided. Retrying in ${delayInSeconds}s.`); ensureSupergraphManager().start(delayInSeconds); }); ensureSupergraphManager().start(); }, onPluginInit({ setSchema }) { if (ensureSupergraphManager().schema) { setSchema(ensureSupergraphManager().schema); } else { // Wait for the first schema to be loaded before before allowing requests to be parsed // We can then remove the onRequestParse hook to avoid async cost on every request let waitForInitialization = new Promise((resolve, reject) => { const onFailure = (evt) => { reject(createGraphQLError('Supergraph failed to load', { originalError: evt.detail.error instanceof Error ? evt.detail.error : undefined, })); }; ensureSupergraphManager().addEventListener('failure', onFailure, { once: true }); ensureSupergraphManager().addEventListener('schema', (evt) => { setSchema(evt.detail.schema); ensureSupergraphManager().removeEventListener('failure', onFailure); resolve(); plugin.onRequestParse = undefined; waitForInitialization = undefined; }, { once: true }); }); plugin.onRequestParse = () => waitForInitialization; } ensureSupergraphManager().addEventListener('schema', (evt) => { setSchema(evt.detail.schema); }); }, onDispose() { return _supergraphManager?.stop(); }, }; return plugin; }