gpt4 book ai didi

graphql - 在 GraphQL 中解析相关数据的优雅且高效的方法

转载 作者:行者123 更新时间:2023-12-02 14:13:57 25 4
gpt4 key购买 nike

解析 GraphQL 中数据的最佳方式是什么

这里我有一个SeekerTypeJobTypeJobsType嵌套在SeekerType

求职者可以申请许多工作。查询求职者时,可以只查询求职者的数据,也可以查询嵌套的JobType并获取jobtype数据。

但问题是,如果不查询嵌套的JobType他不会获取 Jobs 数据,但我的 Seeker resolver in viewerType 也会获取该数据。

因此,在向求职者查询提供数据时,我该如何处理该问题,他要么只想要求职者详细信息,要么也可能想要工作详细信息。

我是否应该使用每个nestedType的resolver并获取父对象,并使用父对象中的字段获取相关数据???

下面的代码仅用于说明和说明,问题是关于解析数据的最佳方式

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() 以带有嵌套的 graphql 字段格式提供完整数据jobs 字段数据也是如此

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.


});
}
});

最佳答案

我认为这是一个关于如何防止过度获取相关数据的问题......即如何在查询搜索者时不一定请求职位数据。

这可能有多种优化和安全动机。

注意事项:

  1. 如果消费者(例如 Web 应用程序)在您的控制之下,您可以在查询搜寻者时避免请求 jobs 字段。如您所知,这是 graphql 的既定目标之一,即仅通过网络将所需的内容返回给消费者,以最大限度地减少网络流量并一次性完成工作。在后端,我想 graphql 引擎足够聪明,如果没有请求,也不会过度获取作业数据。

  2. 例如,如果您更担心安全性或消费者应用程序无意中过度获取超出您控制范围的问题,那么您可以通过创建单独的查询并甚至限制对它们的访问来解决该问题。例如。一个查询 Seeker,另一个查询 SeekerWithJobsData。

  3. 另一种需要考虑的技术是 graphql 指令,它提供了一个包含开关,可用于有条件地服务特定字段。在您的场景中使用此技术的一个优点可能是允许一种方便的方式根据单个 bool 值(例如,)在多个查询中有条件地显示多个字段。工作搜索标志=假。请阅读此处了解指令概述: http://graphql.org/learn/queries/

关于graphql - 在 GraphQL 中解析相关数据的优雅且高效的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42017400/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com