An elegant and efficient way to resolve related data in GraphQL

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) => {

      // getSeekers() provides all the data required for SeekerType fields and it's
          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.


        });
    }
});
+4
source share
2 answers

I’m not sure I fully understand the question, but it seems to me that you are downloading information about people looking for information about yourself and information about the types of work at the same level. You must download them on demand.

, , . , ( )

, , . , .

, dataloader

0

, , ... I.e. .

.

:

+1

Source: https://habr.com/ru/post/1668697/


All Articles