如何使用特定上下文查询 Apollo GraphQL 服务器?

Posted

技术标签:

【中文标题】如何使用特定上下文查询 Apollo GraphQL 服务器?【英文标题】:How to query Apollo GraphQL server with a specific context? 【发布时间】:2019-07-23 09:23:04 【问题描述】:

我正在编写一个 Apollo GraphQL API,它返回来自各个品牌的产品信息。架构的简化版本如下所示:

type Query 
  products: [Product]!


type Product 
  name: String!
  brand: String!

我希望能够查询特定品牌的产品。通常,这很容易通过向Product 对象添加brand 参数来实现:

type Query 
    products(brand: String!): [Product]!

但是,我在不同的应用程序中有多个 GraphQL 客户端,每个客户端都与特定品牌相关联,因此在每个查询中始终传递相同的 brand 参数似乎是多余的。我的架构中还有许多其他对象(订单、交易等),它们是特定于品牌的,需要brand 参数。

此外,我的解析器需要根据品牌查询不同的 API,因此即使是我的架构中的对象,例如 User,在概念上与品牌无关,也可能需要一个 brand 参数,以便解析器知道从哪个 API 获取。

有没有办法为每个客户端设置品牌上下文并让服务器接收此上下文?或者也许有更好的方法来实现这种品牌分离?

【问题讨论】:

【参考方案1】:

我可能会让Brand 成为您的 GraphQL 查询中的一流类型。这并不能使您不必对特定品牌描述的许多查询进行限定,但它至少为您提供了一个共同的起点。然后你会得到一个有点像这样的 API:

type Query 
  brand(name: String!): Brand
  allProducts: [Product!]!

type Brand 
  name: String!
  products: [Product!]!
  # users: [User!]!

type Product 
  name: String!
  brand: Brand! # typical, but not important to your question

如果各种品牌之间的差异在 API 层可见,您还可以考虑使用 GraphQL interface 来描述所有品牌拥有的字段集,但实际上从解析器返回更具体的类型。

按照您描述应用程序的方式,为每个品牌运行一个服务副本也是有意义的,每个品牌都有不同的 GraphQL 端点。这将使您可以直接参数化每个品牌的内部对象配置,并使“当前品牌”成为流程全局上下文。这里最大的限制是,在 GraphQL 级别,一个品牌的对象永远不能引用另一个,如果你有很多品牌,你需要一些好的方法来运行很多服务器。

【讨论】:

谢谢。对我们来说,每个品牌的服务器都需要太多的维护,即使是容器化。你知道 Apollo 是否可以让同一个服务器响应不同的端点?如果是这样,我可以检查端点的req 对象,这将识别品牌。我检查了文档,但找不到有关此方法的任何信息。 我做了更多的研究,可以在 Express 应用程序中使用 Apollo,这将允许将多个端点路由到同一个 Apollo 服务器。另一种方法是在同一个应用程序glitch.com/edit/#!/terrific-trouser?path=server.js:1:0 中拥有多个服务器,这将允许每个品牌共享对象/上下文。但是,您选择拥有多项服务具有扩展优势,因此需要权衡一些利弊。感谢您为我指明正确的方向。

以上是关于如何使用特定上下文查询 Apollo GraphQL 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL:用于查询返回不同类型对象的模式?

如何让 Apollo 客户端重新获取特定查询?

React Apollo - 孩子没有根据结果变化进行更新

如何在 Apollo Server 中正确键入上下文对象?

如何在 react-apollo 中根据上下文使用两个不同的 websocket url?

你如何动态控制 react apollo-client 查询启动?