我们使用 Apollo Federation 作为我们的主要 api 已经有 1.5 年了。联邦网关后面是 6 个子 graphql 服务,它们都在网关处组合。当您拥有跨越不同服务的数据结果集时,此配置确实非常有效。例如,引用购买的用户和与之关联的事件的门票列表等。
我们经历过这种崩溃的一个地方是,当需要一组预先设置的数据时,这些数据已经在另一个子服务(或跨其他子服务)(解析器/路径)中定义。没有办法(我们已经发现)从子服务查询联合以获取一组联合数据,供解析器使用以处理该数据。
例如,假设我们定义了一个 graphql 查询,它查询一个活动的所有门票,并通过联合返回购买者的数据、活动的数据和产品的数据。如果我需要来自解析器的数据集,我需要自己再次进行所有这些查询,复制 dataSource 逻辑并匹配代码中的数据。
一个疯狂的想法是设置apollo-datasource-rest
dataSource 来对我们的网关端点进行查询,作为解析器的数据源。通过这种方式,我们可以请求我们需要的数据,并让 Apollo Federation 按照设计的方式将所有数据拼接在一起。因此,与其解析器查询数据库中所有不同的数据然后匹配它们,我们将从我们的 graphql 网关请求数据,该网关已经定义了该查询。
我们试图通过这样做来避免在子服务中重复一组查询,以获取其他服务中(或跨)已经可用的详细信息。
问题
这真的是个坏主意吗?
这是一个合理的想法吗?
有没有人尝试过这样的事情?
是的,我们必须确保解析器没有循环依赖。在我们的例子中,我看到用于收集突变中的初始数据的“数据源访问网关”。
联合查询示例。在此查询中,event
、allocatedTo
、purchasedBy
和product
都是其他服务中的类型。event
是事件类型,allocatedTo
是purchasedBy
配置文件类型,product
是产品类型。这个查询为我提供了我会说的所有数据,向结果集中的人发送电子邮件通知。尽管从突变的解析器获取这些数据以将这些电子邮件排队意味着我需要自己进行许多查询并通过代码对齐所有数据,而不是使用已经使用已经建立的查询执行此操作的网关/联合。使用查询我们自己的网关的想法apollo-datasource-rest
是以这种形式获取这些数据。不是通过单独的查询和代码来对齐 id 等。
query getRegisteredUsers($eventId: ID!) {
communications {
event(eventId: $eventId) {
registered {
event {
name
}
isAllocated,
hasCheckedIn,
lastUpdatedAt,
allocatedTo {
firstName
lastName
email
}
purchasedBy {
id
firstName
lastName
}
product {
__typename
...on Ticket {
id
name
}
}
}
}
}
}