modularizes find request handler / query / resolver, enables find in graphql

This commit is contained in:
James
2020-04-05 17:24:05 -04:00
parent 85bfc677bf
commit 2d02691a79
7 changed files with 99 additions and 67 deletions

View File

@@ -1,22 +1,44 @@
const { NotFound } = require('../../errors');
const { APIError } = require('../../errors');
const find = (query) => {
return new Promise((resolve, reject) => {
query.Model.find({}, (err, docs) => {
if (err || !docs) {
reject(new NotFound());
}
const find = async (options) => {
try {
const {
Model,
query,
locale,
fallbackLocale,
paginate,
depth,
} = options;
let result = docs;
const mongooseQuery = await Model.buildQuery(query, locale);
if (query.locale) {
docs.setLocale(query.locale, query.fallback);
result = docs.toJSON({ virtuals: true });
}
const paginateQuery = {
options: {},
...paginate,
};
resolve(result);
});
});
if (depth) {
paginateQuery.options.autopopulate = {
maxDepth: depth,
};
}
const result = await Model.paginate(mongooseQuery, paginateQuery);
return {
...result,
docs: result.docs.map((doc) => {
if (locale && doc.setLocale) {
doc.setLocale(locale, fallbackLocale);
}
return doc.toJSON({ virtuals: true });
}),
};
} catch (err) {
throw new APIError();
}
};
module.exports = find;

View File

@@ -0,0 +1,24 @@
const httpStatus = require('http-status');
const { find } = require('../queries');
const findHandler = async (req, res) => {
try {
const result = await find({
Model: req.Model,
paginate: {
page: req.query.page,
limit: req.query.limit,
sort: req.query.sort,
},
depth: req.query.depth,
locale: req.locale,
fallbackLocale: req.query['fallback-locale'],
});
return res.status(httpStatus.OK).json(result);
} catch (err) {
return res.status(400).json(err);
}
};
module.exports = findHandler;

View File

@@ -1,13 +1,13 @@
const create = require('./create');
const destroy = require('./destroy');
const findByID = require('./findByID');
const query = require('./query');
const find = require('./find');
const update = require('./update');
module.exports = {
create,
destroy,
findByID,
query,
find,
update,
};

View File

@@ -1,38 +0,0 @@
const httpStatus = require('http-status');
const query = async (req, res) => {
try {
const mongooseQuery = await req.model.buildQuery(req.query, req.locale);
const paginateQuery = {
options: {},
};
if (req.query.page) paginateQuery.page = req.query.page;
if (req.query.limit) paginateQuery.limit = req.query.limit;
if (req.query.sort) paginateQuery.sort = req.query.sort;
if (req.query.depth) {
paginateQuery.options.autopopulate = {
maxDepth: req.query.depth,
};
}
const result = await req.model.paginate(mongooseQuery, paginateQuery);
return res.status(httpStatus.OK).json({
...result,
docs: result.docs.map((doc) => {
if (req.locale && doc.setLocale) {
doc.setLocale(req.locale, req.query['fallback-locale']);
}
return doc.toJSON({ virtuals: true });
}),
});
} catch (err) {
return res.status(400).json(err);
}
};
module.exports = query;

View File

@@ -6,7 +6,7 @@ const loadPolicy = require('../express/middleware/loadPolicy');
const bindCollectionMiddleware = require('./bindCollection');
const {
query, create, findByID, destroy, update,
find, create, findByID, destroy, update,
} = requestHandlers;
const router = express.Router();
@@ -18,7 +18,7 @@ const registerRoutes = ({ model, config }) => {
setModelLocaleMiddleware());
router.route(`/${config.slug}`)
.get(loadPolicy(config.policies.read), query)
.get(loadPolicy(config.policies.read), find)
.post(loadPolicy(config.policies.create), create);
router.route(`/${config.slug}/:id`)

View File

@@ -3,6 +3,9 @@ const {
GraphQLString,
GraphQLSchema,
GraphQLNonNull,
GraphQLList,
GraphQLInt,
GraphQLBoolean,
} = require('graphql');
const graphQLHTTP = require('express-graphql');
const getBuildObjectType = require('./schema/getBuildObjectType');
@@ -11,7 +14,7 @@ const formatName = require('./utilities/formatName');
const withPolicy = require('./resolvers/withPolicy');
const getLocaleStringType = require('./types/getLocaleStringType');
const getLocaleFloatType = require('./types/getLocaleFloatType');
const { findByID } = require('../collections/queries');
const { find, findByID } = require('../collections/queries');
const Query = {
name: 'Query',
@@ -85,25 +88,42 @@ function init() {
id: { type: GraphQLString },
},
resolve: withPolicy(policies.read, async (_, { id }) => {
const doc = findByID({
return findByID({
depth: 0,
Model: collection.model,
id,
});
return doc;
}),
};
Query.fields[`get${pluralLabel}`] = {
type: collection.graphQLType,
Query.fields[pluralLabel] = {
type: new GraphQLObjectType({
name: pluralLabel,
fields: {
docs: {
type: new GraphQLList(collection.graphQLType),
},
totalDocs: { type: GraphQLInt },
offset: { type: GraphQLInt },
limit: { type: GraphQLInt },
totalPages: { type: GraphQLInt },
page: { type: GraphQLInt },
pagingCounter: { type: GraphQLInt },
hasPrevPage: { type: GraphQLBoolean },
hasNextPage: { type: GraphQLBoolean },
prevPage: { type: GraphQLBoolean },
nextPage: { type: GraphQLBoolean },
},
}),
args: {
where: { type: collection.graphQLWhereInputType },
},
resolve: withPolicy(policies.read, async (_, args, context) => {
return {
image: 'test',
};
resolve: withPolicy(policies.read, async (_, args) => {
return find({
depth: 0,
Model: collection.model,
query: args,
});
}),
};
});

View File

@@ -2,6 +2,7 @@ const {
GraphQLString,
GraphQLFloat,
GraphQLBoolean,
GraphQLInt,
GraphQLList,
// GraphQLInterfaceType,
// GraphQLEnumType,
@@ -150,6 +151,9 @@ const buildWhereInputType = ({ name, fields, parent }) => {
},
})),
},
page: { type: GraphQLInt },
limit: { type: GraphQLInt },
sort: { type: GraphQLString },
},
});
};