如何为 GraphQL 服务器设计以下解析器?
How to design the following resolver for GraphQL server?
我正在使用 mysql 和 sequelize 在 meteor 上使用 react-apollo,我仍然是 JS 的初学者。
假设我的 apollo-server 上有以下解析器函数:
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({ where: args });
},
numberOfPosts(){
return /// the number of selected posts
}
}
我想 select 从满足某些条件的数据库中获取一些数据,然后计算 selected 行的数量和 return 它们在字段中的数量 "numberOfPosts".
findAndCountAll()
returns 一个对象,其中包含 selected 行和计数。我想让我的 post()
到 return 只有 selected 行,我的 numberOfPosts() 到 return 只有 selected 帖子的计数.现在,两者都是 return 由 posts() 编辑的。
我的架构是:
type Post {
id: Int
date: Float
text: String
}
type NumberOfPosts{
total: Int
filtered: Int
}
type Query {
posts(
id: Ind,
offset: Int,
limit: Int,
filter: String): [Post]
numberOfPosts:[NumberOfPosts]
}
schema {
query: Query
}
目标是接收以下格式的数据:
{
"data": {
"numberOfPosts": [
{
"total": 1000,
"filtered": 21
}
],
"posts": [
{
"id": 4,
"date": 5105626122,
"text": "jzybiwutudi"
},
...
]
}
}
我目前的工作:
尝试 1:
let selectedCount;
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({where: args}).then(
function (results) {
selectedCount = results.count;
return results.rows
});
},
numberOfPosts(){
return selectedCount
}
}}
所以我在解析器之外定义了一个帮助变量,并将其设置为 selected 行数,然后计数在 numberOfPosts()
中被 returned,这有效,但问题是,return results.rows
导致错误,我不明白为什么。
另一个问题是,selectedCount
总是之前的行数
尝试 2
另一个似乎有效的解决方案是将参数两次传递到 GraphQL 查询中,如下所示:
{
numberOfPosts(filter: "example") {
total
filtered
}
posts(filter: "example") {
id
date
text
}
}
然后两个解析器函数都知道相同的参数,所以我可以 select 并计算相同的帖子。但这对我来说不合适,因为我必须传递相同的参数两次,它们也会被传递两次...
您应该更多地考虑设计以及每个查询应该做什么。这些查询不应改变数据库或全局状态。
你能做的最好的事情就是简单地定义一个新类型,包括 total
和 filtered
,就像你第一次尝试 NumberOfPosts
那样,还有帖子列表。
因此,您的架构如下:
type Post {
id: Int
date: Float
text: String
}
type PostList {
total: Int
filtered: Int
posts: [Post]
}
type Query {
posts(
id: Ind,
offset: Int,
limit: Int,
filter: String): PostList
}
schema {
query: Query
}
然后你解决 posts
比如:
posts(_, args) {
return Post.findAndCountAll({ where: args }).then(result => {
return {
total: 1000,
filtered: result.count,
posts: result.rows
}
})
}
注意我是如何将 1000 作为总数的。您无法通过 findAndCountAll
获取总行数。如果需要,您可以 运行 并行两个不同的查询并使用 Promise.all
等待它们得到解决。
posts(_, args) {
return Promise.all([
Post.count(),
Post.findAndCountAll({ where: args })
]).then(data => {
return {
total: data[0],
filtered: data[1].count,
posts: data[1].rows
}
})
}
以上代码也可以受益于 ES6's destructuring:
posts(_, args) {
return Promise.all([
Post.count(),
Post.findAndCountAll({ where: args })
]).then(([totalCount, filteredData]) => {
return {
total: totalCount,
filtered: filteredData.count,
posts: filteredData.rows
}
})
}
现在你可以运行:
query {
posts(filter:"example") {
total
filtered
posts {
id
date
text
}
}
}
并得到:
{
"data": {
"posts": {
"total": 1000,
"filtered": 21,
"posts": [
{
"id": 4,
"date": 5105626122,
"text": "jzybiwutudi"
},
...
]
}
}
}
我正在使用 mysql 和 sequelize 在 meteor 上使用 react-apollo,我仍然是 JS 的初学者。 假设我的 apollo-server 上有以下解析器函数:
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({ where: args });
},
numberOfPosts(){
return /// the number of selected posts
}
}
我想 select 从满足某些条件的数据库中获取一些数据,然后计算 selected 行的数量和 return 它们在字段中的数量 "numberOfPosts".
findAndCountAll()
returns 一个对象,其中包含 selected 行和计数。我想让我的 post()
到 return 只有 selected 行,我的 numberOfPosts() 到 return 只有 selected 帖子的计数.现在,两者都是 return 由 posts() 编辑的。
我的架构是:
type Post {
id: Int
date: Float
text: String
}
type NumberOfPosts{
total: Int
filtered: Int
}
type Query {
posts(
id: Ind,
offset: Int,
limit: Int,
filter: String): [Post]
numberOfPosts:[NumberOfPosts]
}
schema {
query: Query
}
目标是接收以下格式的数据:
{
"data": {
"numberOfPosts": [
{
"total": 1000,
"filtered": 21
}
],
"posts": [
{
"id": 4,
"date": 5105626122,
"text": "jzybiwutudi"
},
...
]
}
}
我目前的工作: 尝试 1:
let selectedCount;
export default resolvers = {
Query: {
posts(_, args){
return Post.findAndCountAll({where: args}).then(
function (results) {
selectedCount = results.count;
return results.rows
});
},
numberOfPosts(){
return selectedCount
}
}}
所以我在解析器之外定义了一个帮助变量,并将其设置为 selected 行数,然后计数在 numberOfPosts()
中被 returned,这有效,但问题是,return results.rows
导致错误,我不明白为什么。
另一个问题是,selectedCount
总是之前的行数
尝试 2
另一个似乎有效的解决方案是将参数两次传递到 GraphQL 查询中,如下所示:
{
numberOfPosts(filter: "example") {
total
filtered
}
posts(filter: "example") {
id
date
text
}
}
然后两个解析器函数都知道相同的参数,所以我可以 select 并计算相同的帖子。但这对我来说不合适,因为我必须传递相同的参数两次,它们也会被传递两次...
您应该更多地考虑设计以及每个查询应该做什么。这些查询不应改变数据库或全局状态。
你能做的最好的事情就是简单地定义一个新类型,包括 total
和 filtered
,就像你第一次尝试 NumberOfPosts
那样,还有帖子列表。
因此,您的架构如下:
type Post {
id: Int
date: Float
text: String
}
type PostList {
total: Int
filtered: Int
posts: [Post]
}
type Query {
posts(
id: Ind,
offset: Int,
limit: Int,
filter: String): PostList
}
schema {
query: Query
}
然后你解决 posts
比如:
posts(_, args) {
return Post.findAndCountAll({ where: args }).then(result => {
return {
total: 1000,
filtered: result.count,
posts: result.rows
}
})
}
注意我是如何将 1000 作为总数的。您无法通过 findAndCountAll
获取总行数。如果需要,您可以 运行 并行两个不同的查询并使用 Promise.all
等待它们得到解决。
posts(_, args) {
return Promise.all([
Post.count(),
Post.findAndCountAll({ where: args })
]).then(data => {
return {
total: data[0],
filtered: data[1].count,
posts: data[1].rows
}
})
}
以上代码也可以受益于 ES6's destructuring:
posts(_, args) {
return Promise.all([
Post.count(),
Post.findAndCountAll({ where: args })
]).then(([totalCount, filteredData]) => {
return {
total: totalCount,
filtered: filteredData.count,
posts: filteredData.rows
}
})
}
现在你可以运行:
query {
posts(filter:"example") {
total
filtered
posts {
id
date
text
}
}
}
并得到:
{
"data": {
"posts": {
"total": 1000,
"filtered": 21,
"posts": [
{
"id": 4,
"date": 5105626122,
"text": "jzybiwutudi"
},
...
]
}
}
}