Vulcan/packages/vulcan-lib/lib/modules/apollo.js

107 lines
3.5 KiB
JavaScript
Raw Normal View History

2017-02-12 22:00:13 +08:00
import ApolloClient, { createNetworkInterface, createBatchingNetworkInterface } from 'apollo-client';
import 'cross-fetch/polyfill';
2017-02-12 22:00:13 +08:00
import { Meteor } from 'meteor/meteor';
import { getSetting, registerSetting } from './settings.js';
import { getFragmentMatcher } from './fragment_matcher.js';
2018-01-25 15:03:03 -06:00
import { runCallbacks } from './callbacks.js';
2017-02-06 14:33:34 +08:00
registerSetting('graphQLendpointURL', '/graphql', 'GraphQL endpoint URL');
2017-02-06 14:33:34 +08:00
const defaultNetworkInterfaceConfig = {
2017-02-12 22:00:13 +08:00
path: '/graphql', // default graphql server endpoint
opts: {}, // additional fetch options like `credentials` or `headers`
useMeteorAccounts: true, // if true, send an eventual Meteor login token to identify the current user with every request
batchingInterface: true, // use a BatchingNetworkInterface by default instead of a NetworkInterface
2017-02-12 22:00:13 +08:00
batchInterval: 10, // default batch interval
2017-02-06 14:33:34 +08:00
};
const createMeteorNetworkInterface = (givenConfig = {}) => {
2017-02-12 22:00:13 +08:00
const config = { ...defaultNetworkInterfaceConfig, ...givenConfig };
2017-02-06 14:33:34 +08:00
// absoluteUrl adds a '/', so let's remove it first
let path = config.path;
if (path[0] === '/') {
path = path.slice(1);
}
const defaultUri = Meteor.absoluteUrl(path);
const uri = getSetting('graphQLendpointURL', defaultUri);
2017-02-12 22:00:13 +08:00
// allow the use of a batching network interface; if the options.batchingInterface is not specified, fallback to the standard network interface
const interfaceToUse = config.batchingInterface ? createBatchingNetworkInterface : createNetworkInterface;
// default interface options
const interfaceOptions = {
uri,
2017-02-06 14:33:34 +08:00
opts: {
2017-02-12 22:00:13 +08:00
credentials: 'same-origin', // http://dev.apollodata.com/react/auth.html#Cookie
},
};
2017-02-06 14:33:34 +08:00
2017-02-12 22:00:13 +08:00
// if a BatchingNetworkInterface is used with a correct batch interval, add it to the options
if (config.batchingInterface && config.batchInterval) {
interfaceOptions.batchInterval = config.batchInterval;
}
2017-02-06 14:33:34 +08:00
2017-02-12 22:00:13 +08:00
// if 'fetch' has been configured to be called with specific opts, add it to the options
if (Object.keys(config.opts).length > 0) {
interfaceOptions.opts = config.opts;
}
2017-02-06 14:33:34 +08:00
2017-02-12 22:00:13 +08:00
const networkInterface = interfaceToUse(interfaceOptions);
2017-02-06 14:33:34 +08:00
2018-05-16 11:43:19 +09:00
// console.log('// apollo.js locale:', config.locale);
2017-02-12 22:00:13 +08:00
if (config.useMeteorAccounts) {
networkInterface.use([{
applyBatchMiddleware(request, next) {
2017-02-12 22:00:13 +08:00
const currentUserToken = Meteor.isClient ? global.localStorage['Meteor.loginToken'] : config.loginToken;
2017-02-06 14:33:34 +08:00
2017-02-12 22:00:13 +08:00
if (!currentUserToken) {
next();
return;
}
if (!request.options.headers) {
request.options.headers = new Headers();
}
request.options.headers.Authorization = currentUserToken;
request.options.headers.locale = config.locale;
2017-02-12 22:00:13 +08:00
next();
},
}]);
}
2017-02-06 14:33:34 +08:00
return networkInterface;
};
const meteorClientConfig = networkInterfaceConfig => {
return {
ssrMode: Meteor.isServer,
networkInterface: createMeteorNetworkInterface(networkInterfaceConfig),
queryDeduplication: true, // http://dev.apollodata.com/core/network.html#query-deduplication
addTypename: true,
fragmentMatcher: getFragmentMatcher(),
// Default to using Mongo _id, must use _id for queries.
dataIdFromObject(result) {
if (result._id && result.__typename) {
const dataId = result.__typename + result._id;
return dataId;
}
return null;
},
}
};
export const createApolloClient = options => {
runCallbacks('apolloclient.init.before');
return new ApolloClient(meteorClientConfig(options));
};