Skip to content

Instantly share code, notes, and snippets.

@eyston
Created November 6, 2015 16:53
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eyston/7ec48ceb30213e7fbb36 to your computer and use it in GitHub Desktop.
Save eyston/7ec48ceb30213e7fbb36 to your computer and use it in GitHub Desktop.
let rootValue = {
response: {
timing: {
fields: []
}
}
}
const start = new Date().getTime();
return graphql(schema, query, rootValue, variables).then(response => {
rootValue.response.timing.duration = (new Date().getTime() - start) / 1000;
return {...response, ...rootValue.response};
});
import {GraphQLObjectType,GraphQLScalarType} from 'graphql/type/definition';
function defaultResolveFn(source, args, { fieldName }) {
var property = source[fieldName];
return typeof property === 'function' ? property.call(source) : property;
}
const wrapPromise = (next) => {
return (obj, args, info) => {
try {
return Promise.resolve(next(obj, args, info));
} catch (e) {
return Promise.reject(e);
}
}
}
const withLogging = (next) => {
return (obj, args, info) => {
console.log(`resolving: ${info.parentType.name}#${info.fieldName}`);
return next(obj, args, info);
}
}
const withRandomDelay = (max) => {
return (next) => {
return (obj, args, info) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
next(obj, args, info).then(resolve, reject);
}, Math.floor(Math.random() * max))
});
}
}
}
const withTiming = (next) => {
return (obj, args, info) => {
const start = new Date().getTime();
return Promise.resolve(next(obj, args, info)).then(res => {
info.rootValue.response.timing.fields.push({
type: info.parentType.name,
field: info.fieldName,
args,
duration: (new Date().getTime() - start) / 1000
});
return res;
});
}
}
const schemaFieldsForEach = (schema, fn) => {
Object.keys(schema.getTypeMap())
.filter(typeName => typeName.indexOf('__') !== 0) // remove schema fields...
.map(typeName => schema.getType(typeName))
.filter(type => type instanceof GraphQLObjectType) // make sure its an object
.forEach(type => {
let fields = type.getFields();
Object.keys(fields).forEach(fieldName => {
let field = fields[fieldName]
fn(field, type);
});
});
}
schemaFieldsForEach(schema, (field, type) => {
field.resolve = withTiming(withRandomDelay(1000)(withLogging(wrapPromise(field.resolve || defaultResolveFn))));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment