@graphql-yoga/apollo-managed-federation
Version:
This plugin integrates Apollo Managed Federation into Yoga.
66 lines (65 loc) • 3.18 kB
JavaScript
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;
}