我觉得我缺少明显的东西。我将ID存储为[String]
,希望能够解析为它们代表的完整对象。
这就是我要启用的功能。缺少的成分是解析器:
const bookstore = `
type Author {
id: ID!
books: [Book]
}
type Book {
id: ID!
title: String
}
type Query {
getAuthor(id: ID!): Author
}
`;
const my_query = `
query {
getAuthor(id: 1) {
books { /* <-- should resolve bookIds to actual books I can query */
title
}
}
}
`;
const REAL_AUTHOR_DATA = [
{
id: 1,
books: ['a', 'b'],
},
];
const REAL_BOOK_DATA = [
{
id: 'a',
title: 'First Book',
},
{
id: 'b',
title: 'Second Book',
},
];
我希望能够在 DATA 中存在[Book]
的任何地方将[String]
放入 SCHEMA 中,并让书本从中加载这些字符串。像这样:
const resolve = {
Book: id => fetchToJson(`/some/external/api/${id}`),
};
此解析器不执行任何操作,console.log
甚至都没有被调用
const resolve = {
Book(...args) {
console.log(args);
}
}
但是,这确实得到了一些结果...
const resolve = {
Book: {
id(id) {
console.log(id)
return id;
}
}
}
console.log
确实发出'a'
和'b'
的地方。但是我显然无法将其扩展到X个字段,这太荒谬了。
我的团队当前目前正在做的是从父母那里解决这个问题:
const resolve = {
Author: {
books: ({ books }) => books.map(id => fetchBookById(id)),
}
}
这并不理想,因为也许我有一个type Publisher { books: [Book]}
或type User { favoriteBooks: [Book] }
或type Bookstore { newBooks: [Book] }
。在上述每种情况下,实际数据都是[String]
,我不希望重复此代码:
const resolve = {
X: {
books: ({ books }) => books.map(id => fetchBookById(id)),
}
};
事实上,定义Book.id
解析器会导致console.log触发,这使我认为应该可行,但是我在网上找不到答案,这似乎很不错。常见用例,但我在任何地方都找不到实现细节。
[Books]
的任何地方插入[String]
,而不必在每个地方都[Books] @rest('/external/api')
。感谢您阅读本文。希望有一个我忽略的简单解决方案。如果没有,那么GQL您为什么会这样...
答案 0 :(得分:0)
如果有帮助,您可以这样考虑:类型描述响应中返回的数据的种类,而字段描述数据的实际值。考虑到这一点,只有一个 field 可以有一个解析程序(即一个告诉它解析什么样的值的函数)。 类型的解析器在GraphQL中没有意义。
因此,您可以:
1。处理重复。即使您有十个不同的类型,每个都有一个books
字段,都需要以相同的方式进行解析,但这也没什么大不了的。显然,在生产应用程序中,您不会将数据存储在变量中,并且代码可能会更复杂。但是,可以轻松地将通用逻辑提取到可以在多个解析器之间重用的函数中
const mapIdsToBooks = ({ books }) => books.map(id => fetchBookById(id))
const resolvers = {
Author: {
books: mapIdsToBooks,
},
Library: {
books: mapIdsToBooks,
}
}
2。代替在根级别上获取所有数据。与其在books
字段中编写单独的解析器,不如在getAuthor
解析器中返回作者及其书籍:
function resolve(root, args) {
const author = REAL_AUTHOR_DATA.find(row => row.id === args.id)
if (!author) {
return null
}
return {
...author,
books: author.books.map(id => fetchBookById(id)),
}
}
在处理数据库时,无论如何这通常是更好的方法,因为它减少了您对数据库的请求数量。但是,如果要包装现有的API(听起来就像在做的那样),那么通过这种方法将不会真正获得任何收益。