[英]Apollo GraphQL: How to have a resolver that uses recursion?
My database is modelled as a "forest," or a group of trees.我的数据库被建模为“森林”或一组树。 There are top level nodes that can link to multiple nodes below it, each potentially linking to nodes below it.
有一些顶级节点可以链接到它下面的多个节点,每个节点都可能链接到它下面的节点。
I want to implement a resolver that finds a tree and deletes it.我想实现一个找到树并将其删除的解析器。 This means it has to find a top-level node, search for its children, delete them, and then search for their own children, and so on.
这意味着它必须找到一个顶级节点,搜索其子节点,删除它们,然后搜索自己的子节点,等等。 I'm not sure how to implement this recursion with resolvers.
我不确定如何使用解析器实现此递归。
A recursive structure for this would look something like一个递归结构看起来像
function deleteNodes(rootID) {
root = database.find(id: rootID);
if (!root.childrenIDs) return;
database.delete(id: rootID);
root.childrenIDs.map((childId) => deleteNodes(childId));
}
But I'm not sure how this would work in a resolver, where my code structure looks like:但我不确定这将如何在解析器中工作,我的代码结构如下所示:
module.exports {
Query: {...},
Mutation: {
deleteNodes: async (_, args) => {...}
}
}
How could I design a helper function or recursively call a resolver, or if that's not permitted, how could I execute what I want?我如何设计一个帮助器 function 或递归调用解析器,或者如果不允许这样做,我该如何执行我想要的? Not sure I can call the resolver directly inside the resolver itself.
不确定我可以直接在解析器本身内部调用解析器。
The rule that I have that could help you here is that resolvers should have no business logic in them.我在这里可以帮助您的规则是解析器中不应包含业务逻辑。 I use apollo-server and
DataSources
, but before that I had a similar setup, where the context
object has all of my business logic on it.我使用 apollo-server 和
DataSources
,但在此之前我有一个类似的设置,其中context
object 包含我所有的业务逻辑。 In this way, the resolvers are "just routers", and you can replace GraphQL with REST + Express, or gRPC, or whatever you want.这样,解析器“只是路由器”,您可以将 GraphQL 替换为 REST + Express 或 gRPC 或任何您想要的。
I'm using the DataSources model here, but you could just have a set of "business logic helpers. I do all of this on context
so I can inject them easier for testing.我在这里使用 DataSources model,但您可以只拥有一组“业务逻辑帮助程序。我在
context
完成所有这些,因此我可以更轻松地注入它们进行测试。
That would mean that in this case, your resolver would look like this:这意味着在这种情况下,您的解析器将如下所示:
module.exports = {
Query: {...},
Mutation: {
deleteNodes: async (_, args, context) => {
const result = await context.dataSources.nodes.deleteNodes(args.id);
// something to handle your result
return whatever;
}
}
}
Separately, you would have some nodes
dataSource:另外,您将有一些
nodes
数据源:
const { DataSource } = require('apollo-datasource')
module.exports = class NodesDataSource extends DataSource {
constructor() {
this.database = something;
}
deleteNodes(rootID) {
const root = await this.database.find(id: rootID);
if (!root.childrenIDs) return;
await this.database.delete(id: rootID);
await Promise.all(root.childrenIDs.map((childId) => this.deleteNodes(childId)));
}
}
and in your ApolloServer setup:在您的 ApolloServer 设置中:
const NodesDataSource = require('./datasources/nodes-datasource');
const server = new ApolloServer({
resolvers,
typeDefs,
dataSources: () => {
return {
nodes: new NodesDataSource(),
};
},
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.