Skip to content

Instantly share code, notes, and snippets.

@giautm
Last active February 3, 2017 18:33
Show Gist options
  • Save giautm/3770b6efd05bd48bbae2a666c5453c04 to your computer and use it in GitHub Desktop.
Save giautm/3770b6efd05bd48bbae2a666c5453c04 to your computer and use it in GitHub Desktop.
const {
GraphQLEnumType,
GraphQLObjectType,
GraphQLFloat,
GraphQLID,
GraphQLNonNull,
GraphQLString,
} = require('graphql');
const {
globalIdField,
} = require('graphql-relay');
const {
registerModel,
} = require('./Relay');
const DeliveryOrderType = registerModel({
name: 'DeliveryOrder',
fields: () => ({
id: globalIdField(null, (source) => source._id),
orderNumber: {
type: new GraphQLNonNull(GraphQLString),
},
recipientName: {
type: new GraphQLNonNull(GraphQLString),
},
recipientPhone: {
type: new GraphQLNonNull(GraphQLString),
},
deliveryAddress: {
type: new GraphQLNonNull(GraphQLString),
},
receivables: {
type: new GraphQLNonNull(GraphQLFloat),
},
}),
});
module.exports = {
GraphQLDeliveryOrderType: DeliveryOrderType,
};
const express = require('express');
const graphQLHTTP = require('express-graphql');
const mongoose = require('mongoose');
const {
Schema,
} = require('./schema/Schema');
const {
default: Loader
} = require('./Loader');
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/dev';
const IS_DEVELOPMENT = process.env.NODE_ENV !== 'production';
// Use native promises
mongoose.Promise = global.Promise;
mongoose.connect(MONGODB_URI);
const app = express();
function getSchema() {
if (!IS_DEVELOPMENT) {
return Schema;
}
delete require.cache[require.resolve('./schema/Schema')];
return require('./schema/Schema').Schema; // eslint-disable-line global-require
}
const graphqlSettingsPerRequest = async (request) => {
const startTime = Date.now();
return {
context: {
mongoose,
request,
loaders: new Loader(),
},
graphiql: IS_DEVELOPMENT,
pretty: IS_DEVELOPMENT,
schema: getSchema(),
rootValue: Math.random(),
extensions: (/* { document, variables, operationName, result } */) => ({
runTime: Date.now() - startTime,
}),
formatError: (error) => ({
message: error.message,
stack: IS_DEVELOPMENT ? error.stack.split('\n') : null,
}),
};
}
app.use('/graphql', graphQLHTTP(graphqlSettingsPerRequest));
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
res.status(401).json({
"errors": [
{
"message": "Invalid token",
}
]
});
} else {
next();
}
});
module.exports = app;
const mongoose = require('mongoose');
const DataLoader = require('dataloader');
class Loader {
loaders = {
};
get(modelName) {
if (this.loaders[modelName] === undefined) {
this.loaders[modelName] = this.createCollectionLoader(modelName);
}
return this.loaders[modelName];
}
createCollectionLoader(modelName, checkPermission) {
return new DataLoader((ids) => {
const cachedQuery = {};
return Promise.all(ids.map((id) => {
if (cachedQuery[id] === undefined) {
const model = mongoose.model(modelName);
cachedQuery[id] = model.findById(id).exec();
}
return cachedQuery[id];
}));
});
}
}
module.exports = {
default: Loader,
};
const {
GraphQLObjectType,
} = require('graphql');
const {
fromGlobalId,
nodeDefinitions,
} = require('graphql-relay');
const modelsRegistry = {};
const { nodeInterface, nodeField } = nodeDefinitions(
findObjectByGlobalId, objectToGraphQLType);
function findObjectByGlobalId(globalId, { loaders }) {
const { type, id } = fromGlobalId(globalId);
return loaders.get(type).load(id);
}
function objectToGraphQLType(obj) {
if (obj && obj.constructor) {
const { modelName } = obj.constructor;
return modelsRegistry[modelName] || null;
}
return null;
}
const registerModel = (graphQLObjectTypeConfig) => {
const { name, interfaces } = graphQLObjectTypeConfig;
if (modelsRegistry[name] === undefined) {
modelsRegistry[name] = new GraphQLObjectType(Object.assign({},
graphQLObjectTypeConfig, {
interfaces: [nodeInterface].concat(interfaces || []),
}));
}
return modelsRegistry[name];
};
module.exports = {
nodeField,
nodeInterface,
registerModel,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment