modularizes find request handler / query / resolver, enables find in graphql
This commit is contained in:
@@ -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;
|
||||
|
||||
24
src/collections/requestHandlers/find.js
Normal file
24
src/collections/requestHandlers/find.js
Normal 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;
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
@@ -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`)
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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 },
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user