【问题标题】:GraphQL how to make resolver fetch data only if needed?GraphQL如何使解析器仅在需要时才获取数据?
【发布时间】:2018-11-05 22:49:02
【问题描述】:

我有两种 GraphQL 类型:

type Author {
  id: String!
  name: String!
}

type Book {
  id: String!
  author: Author!
  name: String!
}

在我的数据库中,它是通过books 表中的外键实现的:

表格authors(伪代码)

`id` INTEGER UNSIGNED
`name` STRING

表格books(伪代码)

`id` INTEGER UNSIGNED
`author_id` INTEGER UNSIGNED REFERENCE `authors.id`
`name` STRING

所以当我解决一个像这样的 GraphQL 查询时:

query allTheBooks {
  id
  name
  author {
    id
  }
}

除了获取图书列表的查询之外,我不想再执行 SQL 查询,因为我已经在 books.author_id 字段中拥有数据。

所以我替换了以下代码(js):

Book: {
  async author(book, args, context, info) {
    // this code trigger a database SELECT query that fetch all the fields of the author row associated with the book
    return book.author().get();
  }
}

作者:

Book: {
  async author(book, args, context, info) {
    return {
      id: book.author_id,
    }
  }
}

而且效果很好!

我只有 1 个 SQL 查询,其中我有 1 + N(N 是第一个查询返回的行数)。

但是如何在不按字段发送查询的情况下返回其他字段?

我想可以通过为所有字段返回一个唯一的承诺,这将解决 author 行的所有内容,但我想知道是否有更清洁的方法......

提前感谢您的回答!

【问题讨论】:

    标签: javascript typescript relational-database graphql


    【解决方案1】:

    目前,我找到了一种或多或少干净的方法:

    Book: {
      async author(book, args, context, info) {
        let authorPromise = null;
    
        async function getAuthor() {
          if (authorPromise === null) {
            authorPromise = book.author().get();
          }
    
          return authorPromise;
        }
    
        return new Proxy({}, {
          async get({}, name) {
            if (name === "id") {
              return book.author_id;
            }
    
            if (name in authorFields) {
              const author = await getFile();
              return author[name];
            }
          },
        });
      }
    }
    

    它确保我每行只执行一个查询,但给我留下关于表连接的另一个问题,但我会发布它here :-)

    【讨论】:

      【解决方案2】:

      您不必进行 1 + N 查询。您可以将 N 个查询批处理为 1 个。只需查看 https://github.com/facebook/dataloader

      【讨论】:

      • 我的问题更多是关于避免查询相关数据以获取外键,但感谢您的回答!
      猜你喜欢
      • 1970-01-01
      • 2020-02-26
      • 2021-06-17
      • 2020-09-11
      • 2019-08-03
      • 2019-08-12
      • 2020-03-27
      • 2018-06-16
      • 2018-06-08
      相关资源
      最近更新 更多