简体   繁体   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]
}

This is a fictional schema to illustrate my question.这是一个虚构的模式来说明我的问题。 I have two separate data sources that return lists that need to be joined in order to populate the response.我有两个单独的数据源,它们返回需要加入以填充响应的列表。 The first data source 'employee list api' is an http API I can query to get an authoritative list of employees that I can use to populate the id and name columns.第一个数据源“员工列表 api”是 http API 我可以查询以获得可用于填充idname列的权威员工列表。 For example, I get a response like this:例如,我收到这样的回复:

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

I have a second http API 'employee observation log' I can query to get a list of statuses together with the associated ids.我有第二个 http API '员工观察日志' 我可以查询以获取状态列表以及相关的 ID。 The id allows me to associate the number to an entry in the employee record, and I have a record date. id 允许我将号码与员工记录中的条目相关联,并且我有一个记录日期。 There may be more than one status record, but in GraphQL I want to pick only the most recent one.可能有不止一条状态记录,但在 GraphQL 中我只想选择最近的一条。 Example response:示例响应:

[
    {"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"}
]

Now, I want the graphQL response to return something like this:现在,我希望 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
      }
    ]
  }
}

Since 'employee list api' is the authoritative source about which employees exist, all queries to the 'employee' field should always trigger a query to that api, but the 'employee observation log' api should only be triggered if the 'lastObservedStatus' field is selected in the query.由于'employee list api'是关于哪些员工存在的权威来源,所有对'employee'字段的查询都应始终触发对该api的查询,但'employee observation log'api仅应在'lastObservedStatus'字段时触发在查询中被选中。

For a schema like this, where should the resolvers be registered?对于这样的模式,应该在哪里注册解析器? I've read that the best practice is to always attach resolvers at the leaf nodes, but I'm not sure how that can be done in this situation.我读过,最佳做法是始终在叶节点处附加解析器,但我不确定在这种情况下如何做到这一点。 I'm not even sure what happens if you attach a resolver on subfields of a list.我什至不确定如果您在列表的子字段上附加解析器会发生什么。

I feel like the correct way to handle this is to attach a lambda resolver to the employees field, and in the lambda resolver check the query's selectionSetList to check whether or not the 'lastObservedStatus' field has been selected.我觉得处理此问题的正确方法是将 lambda 解析器附加到employees字段,并在 lambda 解析器中检查查询的 selectionSetList 以检查是否已选择“lastObservedStatus”字段。 If not, then the lambda only queries 'employee list api', but otherwise the lambda also queries 'employee observation log' and does something similar to a SQL join before returning the result.如果不是,则 lambda 仅查询“员工列表 api”,否则 lambda 还会查询“员工观察日志”,并在返回结果之前执行类似于 SQL 连接的操作。 But is that the correct way to handle this?但这是处理这个问题的正确方法吗?

It sounds like what you need is a resolver on the lastObservedStatus field that uses your second API ('employee observation log') as the data source, where the Query field employees is using the first API as its data source.听起来您需要的是lastObservedStatus字段上的解析器,它使用您的第二个 API(“员工观察日志”)作为数据源,其中查询字段employees使用第一个 API 作为其数据源。

This resolver should do a query using the context source field (the 'parent' values, in this case id and name of the Employee which you can reference).此解析器应使用上下文源字段(“父”值,在本例中为您可以引用的Employeeidname )进行查询。 You can reference this in the VTL code using $ctx.source.id for example, or $ctx.source.name if you needed the name.您可以在 VTL 代码中引用它,例如使用$ctx.source.id$ctx.source.name如果您需要名称)。

This resolver should only query the status for a single Employee, since it'll be invoked once per every result in your Query field employees .这个解析器应该只查询单个Employee 的状态,因为它会在您的查询字段employees中的每个结果中调用一次。

There is another option as well, which would be to have a 2 function pipeline resolver where each function points at a different data source:还有另一种选择,即有一个 2 function 管道解析器,其中每个 function 指向不同的数据源:

  • Step 1 resolves all fields except for lastObservedStatus第 1 步解析除lastObservedStatus之外的所有字段
  • Step 2 resolves lastObservedStatus and stitches the results with the $ctx.prev.result .第 2 步解析lastObservedStatus并将结果与$ctx.prev.result

This will be messier to implement, but will require fewer API calls if designed properly.这实现起来会比较麻烦,但如果设计得当,将需要更少的 API 调用。

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

相关问题 在 appsync graphql 中过滤一对多的精确数据 - Filter one to many exact data in appsync graphql 如何将 GraphQL 查询从 python 发送到 AppSync? - How to send a GraphQL query to AppSync from python? 如何通过 graphQL 和 AWS AppSync 发送 JSON 数组以将数据添加到 Dynamo 表? - How to send JSON array through graphQL and AWS AppSync to add data to Dynamo Table? 如何建立从用户池到 aws appsync 模型的数据关系 - How to make a relationship of data from user pool to aws appsync model 多个数据源的图表交互 - Chart Interaction for multiple data sources Apollo Vue (using AWS Amplify/AppSync) Graphql 查询不拉父数据 - Apollo Vue (using AWS Amplify/AppSync) Graphql query does not pull parent data 尝试在 azure 数据工厂中复制数据时如何处理空的 Rest 调用? - How do you handle an empty Rest call when trying to copy data in azure data factory? 如何使用 python 从 cdktf 数据源打印字符串值 - How to print the string value from cdktf data sources with python 如何在 Appsync Lambda 解析器中检索认知识别数据(使用 cdk) - How to retrieve cognito identification data in Appsync Lambda Resolver (Using cdk) AWS appsync graphql 订阅 - AWS appsync graphql subscription
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM