繁体   English   中英

在 AppSync/GraphQL 中如何处理需要来自多个数据源的连接数据的列表?

[英]How do you handle lists that require joined data from multiple data sources in AppSync/GraphQL?

type Employee {
    id: String!
    name: String
    lastObservedStatus: String
}

type Query {
    employees: [Employee]
}

这是一个虚构的模式来说明我的问题。 我有两个单独的数据源,它们返回需要加入以填充响应的列表。 第一个数据源“员工列表 api”是 http API 我可以查询以获得可用于填充idname列的权威员工列表。 例如,我收到这样的回复:

[
    {"id": "001", "name": "Harry"},
    {"id": "002", "name": "Jerry"},
    {"id": "003", "name": "Larry"}
]

我有第二个 http API '员工观察日志' 我可以查询以获取状态列表以及相关的 ID。 id 允许我将号码与员工记录中的条目相关联,并且我有一个记录日期。 可能有不止一条状态记录,但在 GraphQL 中我只想选择最近的一条。 示例响应:

[
    {"id":"002", "TimeStamp":"2021-07-01T12:30:00Z", "status": "eating"},
    {"id":"002", "TimeStamp":"2021-07-01T13:10:00Z", "status": "staring out the window"},
    {"id":"001", "TimeStamp":"2021-07-01T16:00:00Z", "status": "sleeping in lobby"}
]

现在,我希望 graphQL 响应返回如下内容:

{
  "data": {
    "employees": [
      {
        "id": "001",
        "name": "Harry",
        "lastObservedStatus": "sleeping in lobby"
      },
      {
        "id": "002",
        "name": "Jerry",
        "lastObservedStatus": "staring out the window"
      },
      {
        "id": "003",
        "name": "Larry",
        "lastObservedStatus": null
      }
    ]
  }
}

由于'employee list api'是关于哪些员工存在的权威来源,所有对'employee'字段的查询都应始终触发对该api的查询,但'employee observation log'api仅应在'lastObservedStatus'字段时触发在查询中被选中。

对于这样的模式,应该在哪里注册解析器? 我读过,最佳做法是始终在叶节点处附加解析器,但我不确定在这种情况下如何做到这一点。 我什至不确定如果您在列表的子字段上附加解析器会发生什么。

我觉得处理此问题的正确方法是将 lambda 解析器附加到employees字段,并在 lambda 解析器中检查查询的 selectionSetList 以检查是否已选择“lastObservedStatus”字段。 如果不是,则 lambda 仅查询“员工列表 api”,否则 lambda 还会查询“员工观察日志”,并在返回结果之前执行类似于 SQL 连接的操作。 但这是处理这个问题的正确方法吗?

听起来您需要的是lastObservedStatus字段上的解析器,它使用您的第二个 API(“员工观察日志”)作为数据源,其中查询字段employees使用第一个 API 作为其数据源。

此解析器应使用上下文源字段(“父”值,在本例中为您可以引用的Employeeidname )进行查询。 您可以在 VTL 代码中引用它,例如使用$ctx.source.id$ctx.source.name如果您需要名称)。

这个解析器应该只查询单个Employee 的状态,因为它会在您的查询字段employees中的每个结果中调用一次。

还有另一种选择,即有一个 2 function 管道解析器,其中每个 function 指向不同的数据源:

  • 第 1 步解析除lastObservedStatus之外的所有字段
  • 第 2 步解析lastObservedStatus并将结果与$ctx.prev.result

这实现起来会比较麻烦,但如果设计得当,将需要更少的 API 调用。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM