使用和组合另一个公共 apollo graphql api 的最佳方式:federation v 模式拼接
Posted
技术标签:
【中文标题】使用和组合另一个公共 apollo graphql api 的最佳方式:federation v 模式拼接【英文标题】:Best way to consume & combine another public apollo graphql apis: federation v schema stitching 【发布时间】:2020-10-10 00:40:22 【问题描述】:我正在使用 apollo graphql 为 Web 客户端开发 backend-for-frontend (BFF) 解决方案
用例背景,我们的组织有另一个团队拥有的通用 graphql api,我的团队正在创建另一个 graphql 服务器来使用它。这将使我们能够从客户端卸载繁重的计算。我们还希望有一个组合模式,以便在需要时从与 BFF 相同的端点访问通用 api。
我的问题是:
-
建议使用 apollo 联合来组合模式,但是,由于 _entities 字段的强大功能,它强烈建议联合服务器为 private behind a firewall。 为什么会这样?如果数据不是敏感的用户数据,是否会引起关注?我们希望所有服务器都公开。
apollo 模式拼接实际上可能更适合我们的用例,因为它没有说明任何 api 都是私有的。对于我们需要进行的计算,它还可以使 DataSource 逻辑更加精简。但是,我看到的大多数文档都是关于从模式拼接迁移的。 模式拼接会在不久的将来被弃用吗?
是否有另一个选项似乎更适合我错过的账单?
【问题讨论】:
【参考方案1】:隐藏你的联合服务不是必须的,它更像是一个建议。
如果您有一个组合模式,那么为什么要公开非组合的单个模式?
此外,如果您允许客户端与单个服务交互,则管理日志会更加困难,并且速率限制也会变得更加困难。
当您使用组合多个 graphql 模式时,您也可能会相互引用,或者服务 A 可以向服务 B 添加字段等。如果您使用单个服务,查询这些字段会有点问题。 (但它仍然可以工作,只是缺少字段)
是的,模式拼接已被弃用。 Apollo 建议开发者改用 apollo federation。
有一点需要注意,apollo federation 还不支持订阅,所以如果现在订阅是必须的,那么你应该坚持使用模式拼接,直到订阅发布。
【讨论】:
模式拼接并没有被弃用,我相信它不会在不久的将来。它正在积极维护中。 graphql-tools.com/docs/stitch-combining-schemas【参考方案2】:回答您的问题:
为什么会这样?如果数据不是敏感的用户数据,是否会引起关注?
_entities
查询非常强大,正如您所说。例如,如果您使用访问控制快捷方式,则可能很危险。假设您有私人用户。如果您在非联合查询中对Query.user(id: ID)
进行了身份验证检查,则不必对User.homeAddress
进行额外的身份验证检查,因为您无法访问嵌套字段而无法访问顶部级字段。现在让我们假设您的地址服务扩展了用户对象。现在我可以调用地址服务端点(而不是通过网关):
query ($_representations: [_Any!]!)
_entities(representations:$_representations)
... on User
homeAddress
street1
street2
city
state
postalCode
"_representations": [
"__typename": "User",
"id": "user-id-whatever"
]
如果您执行了“惰性访问控制”,您现在就不会受到保护,因为它永远不会首先调用用户服务以获得权限。作为对此的扩展,您可以看到它取决于您是在处理“非敏感”数据还是“不受保护的数据”。
Schema Stitching 已经被弃用了一段时间。看来他们已经弃用它了,因为我再也看不到以前看到的弃用警告了,但据我所知,它“仍在消失”。
不是真的,但我也推荐联邦。老实说,我已经在生产中做了很长时间,而且我一直是联邦的忠实粉丝,我会在大多数情况下推荐它。联合和拼接之间唯一真正的区别是,通过拼接,您必须从支持服务中公开“额外字段”(例如,要将用户添加到对象,服务必须公开userId
,然后您可以使用它来将User
缝合到上面。Federation 通过暴露_entities
来解决这个问题,但这基本上是事情,Federation 会为你做这件事,所以你不必建立代表团。
【讨论】:
以上是关于使用和组合另一个公共 apollo graphql api 的最佳方式:federation v 模式拼接的主要内容,如果未能解决你的问题,请参考以下文章
Apollo GraphQL技术栈概览:如何将所有的功能组合起来
如何使用 Apollo GraphQL 查询结果作为另一个查询的输入?又名:请求链
Apollo Client Angular:如何将从查询中获得的数据作为参数传递给graphql中的另一个查询?