in fusion-plugin-apollo/src/plugin.js [66:185]
export default (renderFn: Render) =>
createPlugin<DepsType, ProvidesType>({
deps: getDeps(),
provides(deps) {
if (__BROWSER__) {
return renderFn;
}
return (el, ctx) => {
return serverRender(el, deps.logger, deps.getDataFromTree).then(() => {
return renderFn(el, ctx);
});
};
},
middleware({
RouteTags,
logger,
schema,
endpoint = '/graphql',
getApolloClient,
apolloContext = ctx => {
return ctx;
},
bodyParserConfig = {},
defaultOptionsConfig = {},
}) {
const renderMiddleware = async (ctx, next) => {
if (!ctx.element) {
return next();
}
let initialState = null;
if (__BROWSER__) {
// Deserialize initial state for the browser
const apolloState = document.getElementById('__APOLLO_STATE__');
if (apolloState) {
initialState = JSON.parse(unescape(apolloState.textContent));
}
}
// Create the client and apollo provider
const client = getApolloClient(ctx, initialState);
ctx.element = (
<ApolloCacheContext.Provider value={client.cache}>
<ApolloProvider client={client}>{ctx.element}</ApolloProvider>
</ApolloCacheContext.Provider>
);
await next();
if (__NODE__) {
// Serialize state into html on server side render
const initialState = client.cache && client.cache.extract();
const serialized = JSON.stringify(initialState);
// eslint-disable-next-line prettier/prettier
const script = html`
<script type="application/json" id="__APOLLO_STATE__">
${String(serialized)}
</script>
`;
ctx.template.body.push(script);
}
};
if (__NODE__ && schema) {
const getApolloContext = ctx => {
if (typeof apolloContext === 'function') {
return apolloContext(ctx);
}
return apolloContext;
};
const server = new ApolloServer({
formatError: error => {
logger && logger.error(error.message, error);
return error;
},
...defaultOptionsConfig,
schema,
// investigate other options
context: ({ctx}) => {
return ctx;
},
executor: async requestContext => {
const fusionCtx = requestContext.context;
const routeTags = RouteTags.from(fusionCtx);
routeTags.name = 'graphql';
const apolloCtx = getApolloContext(fusionCtx);
const client = getApolloClient(fusionCtx, {});
// $FlowFixMe
const queryObservable = client.queryManager.getObservableFromLink(
requestContext.document,
apolloCtx,
requestContext.request.variables
);
return new Promise((resolve, reject) => {
queryObservable.subscribe({
next(x) {
resolve(x);
},
error(err) {
reject(err);
},
});
});
},
});
let serverMiddleware = [];
server.applyMiddleware({
// switch to server.getMiddleware once https://github.com/apollographql/apollo-server/pull/2435 lands
app: {
use: m => {
serverMiddleware.push(m);
},
},
// investigate other options
path: endpoint,
bodyParserConfig,
});
return compose([...serverMiddleware, renderMiddleware]);
} else {
return renderMiddleware;
}
},
});