[英]GraphQL how to make resolver fetch data only if needed?
I have two GraphQL type: 我有两种GraphQL类型:
type Author {
id: String!
name: String!
}
type Book {
id: String!
author: Author!
name: String!
}
In my database, it is implemented by a foreign key inside the books
table: 在我的数据库中,它是由books
表中的外键实现的:
table authors
(pseudo code) 表authors
(伪代码)
`id` INTEGER UNSIGNED
`name` STRING
table books
(pseudo code) 表books
(伪代码)
`id` INTEGER UNSIGNED
`author_id` INTEGER UNSIGNED REFERENCE `authors.id`
`name` STRING
So when I resolve a GraphQL query like: 因此,当我解析GraphQL查询时:
query allTheBooks {
id
name
author {
id
}
}
I dont want to do another SQL query than the one that will get the list of books, as I already have the data in the books.author_id
field. 除了要获取书籍列表的查询之外,我不想执行其他SQL查询,因为我已经在books.author_id
字段中包含了数据。
So I replace the following code (js): 因此,我替换了以下代码(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();
}
}
by: 通过:
Book: {
async author(book, args, context, info) {
return {
id: book.author_id,
}
}
}
And it work well ! 而且效果很好!
I only have 1 SQL query where I had 1 + N (N is the number of rows returned by the first query). 我只有1个SQL查询,其中我有1 + N(N是第一个查询返回的行数)。
But how can I return the other fields without sending a query by field ? 但是,如何在不按字段发送查询的情况下返回其他字段?
I imagine that it's possible by returning an unique promise for all the fields, that will resolve with the all the content of the author
row, but I wonder if there is a cleaner way... 我想这有可能通过为所有字段返回一个唯一的promise来解决author
行的所有内容,但是我想知道是否有更干净的方法...
Thank you in advance for your answer ! 预先感谢您的答复!
For now, I find a more or less clean way to do this: 就目前而言,我发现一种或多或少的干净方法可以做到这一点:
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];
}
},
});
}
}
It ensure me to do only one query per row, but leave me with another question about the joining of the tables, but I'll post it here :-) 它确保我每行只执行一个查询,但又给我一个关于表联接的问题,但我将其发布在这里 :-)
You don't have to make 1 + N query. 您不必进行1 + N查询。 You can batch N queries into 1. Just check out https://github.com/facebook/dataloader . 您可以将N个查询批处理为1个。只需签出https://github.com/facebook/dataloader即可 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.