簡體   English   中英

GraphQL如何僅在需要時使解析器獲取數據?

[英]GraphQL how to make resolver fetch data only if needed?

我有兩種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是第一個查詢返回的行數)。

但是,如何在不按字段發送查詢的情況下返回其他字段?

我想這有可能通過為所有字段返回一個唯一的promise來解決author行的所有內容,但是我想知道是否有更干凈的方法...

預先感謝您的答復!

就目前而言,我發現一種或多或少的干凈方法可以做到這一點:

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];
        }
      },
    });
  }
}

它確保我每行只執行一個查詢,但又給我一個關於表聯接的問題,但我將其發布在這里 :-)

您不必進行1 + N查詢。 您可以將N個查詢批處理為1個。只需簽出https://github.com/facebook/dataloader即可

暫無
暫無

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

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