split context creation to avoid unecessary computations

This commit is contained in:
Eric Burel 2018-10-08 14:06:25 +02:00
parent d78c6edab9
commit e75e199dc2
2 changed files with 29 additions and 27 deletions

View file

@ -22,7 +22,7 @@ export let executableSchema;
import './settings';
import { engineConfig } from './engine';
import { defaultConfig, defaultOptions } from './defaults';
import computeContext from './computeContext';
import { initContext, computeContextFromReq } from './context.js';
import getPlaygroundConfig from './playground';
/**
@ -37,6 +37,7 @@ const createApolloServer = ({ options: givenOptions = {}, config: givenConfig =
// get the options and merge in defaults
const options = { ...defaultOptions, ...givenOptions };
const context = initContext(options.context);
// given options contains the schema
const apolloServer = new ApolloServer({
engine: engineConfig,
@ -46,7 +47,7 @@ const createApolloServer = ({ options: givenOptions = {}, config: givenConfig =
// this replace the previous syntax graphqlExpress(async req => { ... })
// this function takes the context, which contains the current request,
// and setup the options accordingly ({req}) => { ...; return options }
context: computeContext(options.context, contextFromReq)
context: computeContextFromReq(context, contextFromReq)
});
// default function does nothing

View file

@ -13,7 +13,7 @@
//import deepmerge from 'deepmerge';
import DataLoader from 'dataloader';
import { getSetting } from '../../modules/settings.js';
import { _hashLoginToken, _tokenExpiration } from '../accounts_helpers';
import { _hashLoginToken, _tokenExpiration } from '../accounts_helpers.js';
import { Collections } from '../../modules/collections.js';
import { runCallbacks } from '../../modules/callbacks.js';
import findByIds from '../../modules/findbyids.js';
@ -21,7 +21,31 @@ import { GraphQLSchema } from '../../modules/graphql.js';
import { Utils } from '../../modules/utils.js';
import _merge from 'lodash/merge';
const computeContext = (currentContext, contextFromReq) => {
/**
* Called once on server creation
* @param {*} currentContext
*/
export const initContext = currentContext => {
let context;
if (currentContext) {
context = { ...currentContext };
} else {
context = {};
}
// merge with custom context
// TODO: deepmerge created an infinite loop here
context = _merge({}, context, GraphQLSchema.context);
// go over context and add Dataloader to each collection
Collections.forEach(collection => {
context[collection.options.collectionName].loader = new DataLoader(ids => findByIds(collection, ids, context), {
cache: true
});
});
return context;
};
// Call on every request
export const computeContextFromReq = (currentContext, contextFromReq) => {
// givenOptions can be either a function of the request or an object
const getBaseContext = req => (contextFromReq ? { ...currentContext, ...contextFromReq(req) } : currentContext);
const setupAuthToken = async (context, req) => {
@ -50,14 +74,6 @@ const computeContext = (currentContext, contextFromReq) => {
}
}
};
// go over context and add Dataloader to each collection
const setupDataLoader = context => {
Collections.forEach(collection => {
context[collection.options.collectionName].loader = new DataLoader(ids => findByIds(collection, ids, context), {
cache: true
});
});
};
// create options given the current request
const handleReq = async ({ req }) => {
@ -66,13 +82,6 @@ const computeContext = (currentContext, contextFromReq) => {
context = getBaseContext(req);
if (context) {
// don't mutate the context provided in options
context = { ...context };
} else {
context = {};
}
// note: custom default resolver doesn't currently work
// see https://github.com/apollographql/apollo-server/issues/716
// options.fieldResolver = (source, args, context, info) => {
@ -84,12 +93,6 @@ const computeContext = (currentContext, contextFromReq) => {
//add the headers to the context
context.headers = req.headers;
// merge with custom context
// TODO: deemerge created an infinite loop here
context = _merge({}, context, GraphQLSchema.context);
setupDataLoader(context);
// console.log('// apollo_server.js user-agent:', req.headers['user-agent']);
// console.log('// apollo_server.js locale:', req.headers.locale);
@ -100,5 +103,3 @@ const computeContext = (currentContext, contextFromReq) => {
return handleReq;
};
export default computeContext;