【问题标题】:Apollo GraphQL: How to have a resolver that uses recursion?Apollo GraphQL:如何拥有使用递归的解析器?
【发布时间】:2021-07-25 23:58:22
【问题描述】:

我的数据库被建模为“森林”或一组树。有一些顶级节点可以链接到它下面的多个节点,每个节点都可能链接到它下面的节点。

我想实现一个解析器,它可以找到一棵树并将其删除。这意味着它必须找到一个顶级节点,搜索其子节点,删除它们,然后搜索自己的子节点,等等。我不确定如何使用解析器实现此递归。

这个的递归结构看起来像

function deleteNodes(rootID) {
    root = database.find(id: rootID);
    if (!root.childrenIDs) return;
    database.delete(id: rootID);
    root.childrenIDs.map((childId) => deleteNodes(childId));
}

但我不确定这在解析器中如何工作,我的代码结构如下所示:

module.exports {
    Query: {...},
    Mutation: {
        deleteNodes: async (_, args) => {...}
    }
}

我如何设计辅助函数或递归调用解析器,或者如果不允许这样做,我该如何执行我想要的?不确定我是否可以直接在解析器内部调用解析器。

【问题讨论】:

  • 使用一个命名函数,并像你一样递归调用它。没有理由让deleteNodes 成为箭头函数。

标签: javascript apollo react-apollo apollo-server resolver


【解决方案1】:

我在这里可以帮助您的规则是解析器中不应包含业务逻辑。我使用 apollo-server 和 DataSources,但在此之前我有一个类似的设置,context 对象上有我所有的业务逻辑。这样,解析器“只是路由器”,您可以将 GraphQL 替换为 REST + Express、gRPC 或任何您想要的。

我在这里使用 DataSources 模型,但您可以只拥有一组“业务逻辑助手。我在 context 上完成所有这些工作,这样我可以更轻松地注入它们进行测试。

这意味着在这种情况下,您的解析器将如下所示:

module.exports = {
  Query: {...},
  Mutation: {
    deleteNodes: async (_, args, context) => {
      const result = await context.dataSources.nodes.deleteNodes(args.id);
      // something to handle your result
      return whatever;
    }
  }
}

另外,你会有一些 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)));
  }
}

在您的 ApolloServer 设置中:

const NodesDataSource = require('./datasources/nodes-datasource');

const server = new ApolloServer({
  resolvers,
  typeDefs,
  dataSources: () => {
    return {
      nodes: new NodesDataSource(),
    };
  },
});

【讨论】:

    猜你喜欢
    • 2018-07-31
    • 2021-09-25
    • 2020-09-12
    • 2021-07-29
    • 2020-09-11
    • 2021-01-25
    • 2017-08-25
    • 2019-04-06
    • 2020-01-28
    相关资源
    最近更新 更多