具有逻辑的GraphQL批处理

时间:2018-09-27 12:47:40

标签: graphql apollo react-apollo

在GraphQL模式中,我遇到以下情况:

type User {
  id: Float
  name: String
  cityId: Float
}

type City {
  id: Float
  country: String
}

在客户端上,我需要有关UserCity的信息。但是,为了加载City,我必须知道它的ID,因此我不能仅对这些请求进行批处理。是否可以使用逻辑发出批处理请求,所以从客户端我向一个请求发出了两个查询,并且可能添加了一些附加信息,当第一个请求完成时,它从中获取ID,然后发出另一个请求。

之后,User和City都转到客户端。这么说就是内部联接,所以我想有一个请求来加载连接的数据。

我无法更改架构,但是可以向客户端或服务器添加库等。

谢谢。

1 个答案:

答案 0 :(得分:0)

  

PS。对不起,我刚刚注意到你说你不能改变   模式。我将其保留在那里以备将来参考,但不能   可能会解决您的问题。

我建议按照以下方式重新安排您的架构。我没有足够的信息来满足您的需求。但是我建议这个。

type User {
 id: Float
 name: String
 city: City
 #for this city field there will be additional resolver binded to data loader
}
type City {
  id: Float
  country: String
}

这种查询方式如下

query getUsers {
  users {
    id
    name
    city {
      id
      country
    }
  }
}

可以使用Relay规范中的UserConnection,但现在让我们保持简单。 在服务器端,您将需要实现两个解析器...首先是请求用户列表,然后是城市字段的解析器。请注意,解析器具有不同的上下文。为了避免N + 1请求问题和将城市请求批量处理为1。为城市实施data loader可以减少对数据库的请求数量,这将很有用。简单的模式应该是

  1. 用户解析器,获取用户并将其返回到用户解析器中。 CityId 是每次使用的有效载荷的一部分
  2. 由于城市是选择集的第二级,因此您将在解析程序功能的第一个参数中接收每个用户。您将使用countryId将其传递给Countrys数据加载器
  3. 国家/地区数据加载器会将每个国家/地区的请求一起批处理。数据加载器会将countryIds转换为国家/地区值,并为每个用户返回它们。
  4. GraphQL服务器将解决整个查询,并将每个城市分配给每个用户

这是我所知道的处理此问题的最佳方法,并且还将引导您更好地构建架构,因为您将利用appollo存储的规范化,并且我认为使用这种数据格式会更容易在前端。希望我不要在您的帖子中遗漏任何东西,这些信息对您有用。整个问题就是将国家/地区嵌套到用户中,这会导致N + 1请求问题,并减少数据加载程序的N + 1问题的性能问题。