From 2d02691a79de98052fa80beb204789d4f681f586 Mon Sep 17 00:00:00 2001 From: James Date: Sun, 5 Apr 2020 17:24:05 -0400 Subject: [PATCH] modularizes find request handler / query / resolver, enables find in graphql --- src/collections/queries/find.js | 52 ++++++++++++++++------- src/collections/requestHandlers/find.js | 24 +++++++++++ src/collections/requestHandlers/index.js | 4 +- src/collections/requestHandlers/query.js | 38 ----------------- src/collections/routes.js | 4 +- src/graphql/init.js | 40 ++++++++++++----- src/graphql/schema/buildWhereInputType.js | 4 ++ 7 files changed, 99 insertions(+), 67 deletions(-) create mode 100644 src/collections/requestHandlers/find.js delete mode 100644 src/collections/requestHandlers/query.js diff --git a/src/collections/queries/find.js b/src/collections/queries/find.js index cd477c9f35..37b8fd2f09 100644 --- a/src/collections/queries/find.js +++ b/src/collections/queries/find.js @@ -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; diff --git a/src/collections/requestHandlers/find.js b/src/collections/requestHandlers/find.js new file mode 100644 index 0000000000..b5d9685626 --- /dev/null +++ b/src/collections/requestHandlers/find.js @@ -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; diff --git a/src/collections/requestHandlers/index.js b/src/collections/requestHandlers/index.js index 59be6f1bbb..e8c34b6a64 100644 --- a/src/collections/requestHandlers/index.js +++ b/src/collections/requestHandlers/index.js @@ -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, }; diff --git a/src/collections/requestHandlers/query.js b/src/collections/requestHandlers/query.js deleted file mode 100644 index 667b3cb00b..0000000000 --- a/src/collections/requestHandlers/query.js +++ /dev/null @@ -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; diff --git a/src/collections/routes.js b/src/collections/routes.js index d78daf2f8f..0462793767 100644 --- a/src/collections/routes.js +++ b/src/collections/routes.js @@ -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`) diff --git a/src/graphql/init.js b/src/graphql/init.js index 950c013d88..ffaf78c435 100644 --- a/src/graphql/init.js +++ b/src/graphql/init.js @@ -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, + }); }), }; }); diff --git a/src/graphql/schema/buildWhereInputType.js b/src/graphql/schema/buildWhereInputType.js index a832ca91a6..6c2aa87502 100644 --- a/src/graphql/schema/buildWhereInputType.js +++ b/src/graphql/schema/buildWhereInputType.js @@ -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 }, }, }); };