What could be the best way for data in GraphQL resolve
Here I have SeekerTypeand JobType, JobsTypeinvested inSeekerType
The crawler can address many tasks. When querying the crawler, you can simply query the crawlerβs data, as well as query the nested ones JobTypeand also get the job type data.
But the question is that If One does not ask for nested JobType
he will not get the data Jobs, but my Seeker resolverin viewerTypewill also extract the data.
So, providing the data to the search query, how can I deal with this, either he can only want information about the people who are looking for information, or he may also need the details of the tasks.
Should I use resolvereach nested Type and get the parent, and also get the corresponding data using the fields from the parent
The code below is just for illustration and clarification, the question is about the best way to resolve data
ViewerType.js
const Viewer = new GraphQLObjectType({
name: 'Viewer',
fields: () => ({
Seeker: {
type: SeekerConnection,
args: _.assign({
seekerId: { type: GraphQLID },
status: { type: GraphQLString },
shortlisted: { type: GraphQLInt },
}, connectionArgs),
resolve: (obj, args, auth, rootValue) => {
const filterArgs = getFilters(args) || {};
return connectionFromPromisedArray(getSeekers(filterArgs), args)
.then((data) => {
JobsType fields
data.args = filterArgs;
return data;
}).catch(err => new Error(err));
},
},
}),
});
SeekerType.js
const SeekerType = new GraphQLObjectType({
name: 'SeekerType',
fields: () => ({
id: globalIdField('SeekerType', obj => obj._id),
userId: {
type: GraphQLID,
resolve: obj => obj._id,
},
email: { type: GraphQLString },
password: { type: GraphQLString },
firstName: { type: GraphQLString },
lastName: { type: GraphQLString },
imageLink: { type: GraphQLString },
education: { type: GraphQLString },
address: { type: GraphQLString },
jobs: {
type: new GraphQLList(JobType),
},
}),
interfaces: [nodeInterface],
});
getSeekers()provide complete data in the form of graphql field format with embedded
Jobsfield data too
const getSeekers = filterArgs => new Promise((resolve, reject) => {
if (Object.keys(filterArgs).length === 0) {
Seeker.find(filterArgs, { password: 0 }, (err, d) => {
if (err) return reject(err);
return resolve(d);
});
} else {
async.parallel([
(callback) => {
filterArgs._id = filterArgs.seekerId;
delete filterArgs.seekerId;
Seeker.find(filterArgs).lean()
.exec((err, d) => {
if (err) return callback(err);
if (err === null && d === null) return callback(null);
callback(null, d);
});
},
(callback) => {
filterArgs.seekerId = filterArgs._id;
delete filterArgs._id;
Applicant.find(filterArgs).populate('jobId').lean()
.exec((err, resp) => {
if (err) return callback(err);
callback(null, resp);
});
},
], (err, data) => {
const cleanedData = {
userData: data[0],
userJobMap: data[1],
};
const result = _.reduce(cleanedData.userData, (p, c) => {
if (c.isSeeker) {
const job = _.filter(cleanedData.userJobMap,
v => _.isEqual(v.seekerId, c._id));
const arr = [];
_.forEach(job, (i) => {
arr.push(i.jobId);
});
const t = _.assign({}, c, { jobs: arr });
p.push(t);
return p;
}
return reject('Not a Seekr');
}, []);
if (err) reject(err);
resolve(result);
// result have both SeekerType data and nested type
JobType data too.
});
}
});