簡體   English   中英

Apollo GraphQL:如何擁有使用遞歸的解析器?

[英]Apollo GraphQL: How to have a resolver that uses recursion?

我的數據庫被建模為“森林”或一組樹。 有一些頂級節點可以鏈接到它下面的多個節點,每個節點都可能鏈接到它下面的節點。

我想實現一個找到樹並將其刪除的解析器。 這意味着它必須找到一個頂級節點,搜索其子節點,刪除它們,然后搜索自己的子節點,等等。 我不確定如何使用解析器實現此遞歸。

一個遞歸結構看起來像

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

我如何設計一個幫助器 function 或遞歸調用解析器,或者如果不允許這樣做,我該如何執行我想要的? 不確定我可以直接在解析器本身內部調用解析器。

我在這里可以幫助您的規則是解析器中不應包含業務邏輯。 我使用 apollo-server 和DataSources ,但在此之前我有一個類似的設置,其中context object 包含我所有的業務邏輯。 這樣,解析器“只是路由器”,您可以將 GraphQL 替換為 REST + Express 或 gRPC 或任何您想要的。

我在這里使用 DataSources model,但您可以只擁有一組“業務邏輯幫助程序。我在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(),
    };
  },
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM