简体   繁体   English

如何为GraphQL服务器设计以下解析器?

[英]How to design the following resolver for GraphQL server?

I am using react-apollo on meteor with mysql and sequelize, I am still a beginner in JS. 我正在使用带有mysql和sequelize的meteor的react-apollo,我仍然是JS的初学者。 Lets assume I have the following resolver function on my apollo-server: 假设我的apollo-server上有以下解析器函数:

 export default resolvers = {
     Query: {
         posts(_, args){
             return Post.findAndCountAll({ where: args   });
         },
         numberOfPosts(){
             return /// the number of selected posts
         }
     }

I would like to select some data from the database where some conditions are met and then count the amount of selected rows and return them in the field "numberOfPosts". 我想从数据库中选择满足某些条件的一些数据,然后计算所选行的数量并在“numberOfPosts”字段中返回它们。 findAndCountAll() returns an object, which contains the selected rows and the count. findAndCountAll()返回一个对象,其中包含选定的行和计数。 I would like to get my post() to return only the selected rows, and my numberOfPosts() to return only the count of the selected posts. 我想让我的post()只返回选定的行,而我的numberOfPosts()只返回所选帖子的数量。 Right now, both is returned by posts(). 现在,两者都是由posts()返回的。

My schema is: 我的架构是:

 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
}

The Goal is to receive data in the following format: 目标是以下列格式接收数据:

{
  "data": {
    "numberOfPosts": [
      {
        "total": 1000,
        "filtered": 21
      }
    ],
    "posts": [
      {
        "id": 4,
        "date": 5105626122,
        "text": "jzybiwutudi"
      },
      ...
    ]
  }
}

My work so far: Try 1: 到目前为止我的工作:尝试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
        }
    }}

So I am defining a helping variable outside of resolvers, and set it to the number of selected rows, then the count is returned in numberOfPosts() , which works, but the problem with this is, return results.rows causes an error, and I do not understand why. 所以我在解析器之外定义一个帮助变量,并将其设置为所选行的数量,然后在numberOfPosts()返回计数,这有效,但问题是, return results.rows会导致错误,并且我不理解为什么。

another issue is, that selectedCount is always the previous number of rows 另一个问题是, selectedCount始终是前一行数

Try 2 试试2

Another solution that seems to work is to Pass the arguments twice into the GraphQL query, like so: 另一个似乎有用的解决方案是将参数传递两次到GraphQL查询中,如下所示:

{
  numberOfPosts(filter: "example") {
    total
    filtered
  }
  posts(filter: "example") {
    id
    date
    text
  }
}

Then both resolver functions know the same arguments, so I can select and count the same posts. 然后两个解析器函数都知道相同的参数,所以我可以选择和计算相同的帖子。 But this looks not right to me, since I have to pass the same args twice, they will also be transmitted twice... 但这看起来不对我,因为我必须两次传递相同的args,它们也会被传输两次......

You should think more about the design and what each of those queries should do. 您应该更多地考虑设计以及每个查询应该做些什么。 Those queries should not mutate the database or the global state. 这些查询不应该改变数据库或全局状态。

The best thing you can do is to simply define a new type that includes total and filtered , like what you did as NumberOfPosts in your first try, and also the list of posts. 您可以做的最好的事情就是简单地定义一个包含totalfiltered的新类型,就像您在第一次尝试时作为NumberOfPosts所做的那样,以及帖子列表。

So, your schema would be like: 所以,你的架构将是这样的:

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
}

And you resolve posts like: 你解决了以下posts

posts(_, args) {
  return Post.findAndCountAll({ where: args }).then(result => {
    return {
      total: 1000,
      filtered: result.count,
      posts: result.rows
    }
  })
}

Notice how I just put 1000 for the total number. 请注意我如何将总数设为1000。 You can not get the total number of rows with findAndCountAll . 您无法使用findAndCountAll获取总行数。 If you that, need you can run two different queries in parallel and use Promise.all to wait for them to be resolved. 如果你这样做,需要你可以并行运行两个不同的查询,并使用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
    }
  })
}

The above code also could benefit from ES6's destructuring : 上述代码也可以从ES6的解构中受益:

posts(_, args) {
  return Promise.all([
    Post.count(),
    Post.findAndCountAll({ where: args })
  ]).then(([totalCount, filteredData]) => {
    return {
      total: totalCount,
      filtered: filteredData.count,
      posts: filteredData.rows
    }
  })
}

Now you can run: 现在你可以运行:

query {
  posts(filter:"example") {
    total
    filtered
    posts {
      id
      date
      text
    }
  }
}

and get: 得到:

{
  "data": {
    "posts": {
      "total": 1000,
      "filtered": 21,
      "posts": [
        {
          "id": 4,
          "date": 5105626122,
          "text": "jzybiwutudi"
        },
        ...
      ]
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何查询firestore()中的graphQL解析器? - How to query firestore() for graphQL resolver? 如何在GraphQL解析器中访问请求对象(使用Apollo-Server-Express) - How to access the request object inside a GraphQL resolver (using Apollo-Server-Express) 如何在 JavaScript 中调试 GraphQL 解析器? - How do I debug a GraphQL resolver in JavaScript? 如何对graphql解析器实施防护 - How a guard can be implemented to a graphql resolver 如何在 GraphQL 解析器中添加 redis 客户端进行缓存 - How to add redis client for caching in GraphQL resolver Apollo GraphQL:如何拥有使用递归的解析器? - Apollo GraphQL: How to have a resolver that uses recursion? 如何解决nodejs + graphql上的异步s3解析器上传? - how to resolve async s3 resolver upload on nodejs + graphql? GraphQL-subscriptions:如何在订阅解析器中获取已发布的对象 - GraphQL-subscriptions: How to get published object in subscription resolver GraphQL如何仅在需要时使解析器获取数据? - GraphQL how to make resolver fetch data only if needed? 如何在Apollo GraphQL解析器的一个函数中解析2种不同的方法? - How to resolve 2 different methods in one function on Apollo GraphQL resolver?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM