在 aws appsync 解析器中添加额外字段

Posted

技术标签:

【中文标题】在 aws appsync 解析器中添加额外字段【英文标题】:Adding extra field in aws appsync resolver 【发布时间】:2019-07-06 01:40:40 【问题描述】:

我的架构中的用户和组之间存在多对多关系,并带有一个用于关系级别的额外枚举字段。我能够将额外的关系字段添加到我的数据集,但我收到架构验证错误:

"提供的关键元素与架构不匹配(服务: 亚马逊DynamoDBv2;状态码:400;错误代码:验证异常; 请求 ID:2615V0KG8272IHVENE3DBSBCTVVV4KQNSO5AEMVJF66Q9ASUAAJG)"

架构:

type Group 
    id: ID!
    created: AWSDateTime!
    createdById: ID!
    createdBy: User!
    title: String!
    description: String
    users(first: Int, after: String): GroupUsersConnection


enum GroupRoles 
    admin
    user


type GroupUsers 
    id: ID!
    created: AWSDateTime!
    role: GroupRoles!
    userId: ID!
    groupId: ID!


type GroupConnection 
    items: [Group]
    nextToken: String


type GroupUsersConnection 
    items: [UserWithRole]
    nextToken: String


type Mutation 
    createGroup(input: CreateGroupInput!): Group
    createUser(input: CreateUserInput!): User
    createGroupUsers(input: CreateGroupUsersInput!): GroupUsers


type Query 
    getGroup(id: ID!): Group
    listGroups(filter: TableGroupFilterInput, limit: Int, nextToken: String): GroupConnection   
    getUser(id: ID!): User
    listUsers(filter: TableUserFilterInput, limit: Int, nextToken: String): UserConnection


input TableGroupFilterInput 
    id: TableIDFilterInput
    created: TableStringFilterInput
    createdById: TableIDFilterInput
    title: TableStringFilterInput
    description: TableStringFilterInput


input TableUserFilterInput 
    id: TableIDFilterInput
    created: TableStringFilterInput
    email: TableStringFilterInput
    password: TableStringFilterInput
    name: TableStringFilterInput
    avatar: TableStringFilterInput
    isOnline: TableBooleanFilterInput


type User 
    id: ID!
    created: AWSDateTime!
    email: AWSEmail!
    password: String!
    name: String
    avatar: String
    isOnline: Boolean!
    groups(first: Int, after: String): UserGroupsConnection


type UserConnection 
    items: [User]
    nextToken: String


type UserGroupsConnection 
    items: [Group]
    nextToken: String


type UserWithRole 
    id: ID!
    created: AWSDateTime!
    email: AWSEmail!
    password: String!
    name: String
    avatar: String
    isOnline: Boolean!
    role: GroupRoles!


schema 
    query: Query
    mutation: Mutation

GroupUsersConnection.items 的解析器,UserTable 作为数据源:

##--------------------------
## request mapping template
##--------------------------
#if( $ctx.source.items.isEmpty() )

    "version" : "2017-02-28",
    "operation" : "Scan",
    "consistentRead": true

#else
  #set($userIds = [])
  #foreach($groupUser in $ctx.source.items)    
      #set($userIdMap = )
      $util.qr($userIdMap.put("id", $util.dynamodb.toString($groupUser.get("userId"))))
      $util.qr($userIds.add($userIdMap))
  #end

  
      "version" : "2018-05-29",
      "operation" : "BatchGetItem",
      "tables" : 
          "UserTable": 
              "keys": $util.toJson($userIds),
              "consistentRead": true
          
      
  
#end

##--------------------------
## response mapping template
##--------------------------
#if ( ! $ctx.result.data )
    $util.toJson([])
#else
    #foreach($user in $ctx.result.data.UserTable)
        #set($idx = $foreach.count-1)
        #set($role = $ctx.source.items.get(0).get("role"))
        $util.qr($user.put("role", $role))
        $util.qr($usersWithRoles.add($user))        
    #end
    $util.toJson($ctx.result.data.UserTable)
#end

这是我尝试运行的查询,结果完整:

query ListGroups 
  listGroups 
    items 
      id
      title
      createdById
      createdBy 
        name
        email
      
      users 
        items 
          id
          name
          role
        
      
    
  



  "data": 
    "listGroups": 
      "items": [
        
          "id": "72423554-fe02-4644-92e4-4bd2a2702d85",
          "title": "My first group",
          "createdById": "e626fab4-b099-4736-91f0-dcbf5fc2e47e",
          "createdBy": 
            "name": "John Doe",
            "email": "john@doe.com"
          ,
          "users": 
            "items": [
              null
            ]
          
        
      ]
    
  ,
  "errors": [
    
      "path": [
        "listGroups",
        "items",
        0,
        "users",
        "items",
        0,
        "role"
      ],
      "data": null,
      "errorType": "DynamoDB:AmazonDynamoDBException",
      "errorInfo": null,
      "locations": [
        
          "line": 105,
          "column": 11,
          "sourceName": null
        
      ],
      "message": "The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: NB3G15C13BUMEQ3OK6***VA3LFVV4KQNSO5AEMVJF66Q9ASUAAJG)"
    
  ]

【问题讨论】:

【参考方案1】:

这似乎是 400 错误,这可能意味着您的请求映射模板结构与 Amazon DynamoDB 键结构不匹配。

请从您的 API 的设置页面启用 CloudWatch 日志(带有“全部”选项)。完成后,再次运行相同的查询。这将在日志中记录评估的 RequestMapping 模板。然后,您可以对 DynamoDB 的查询进行内省,并将其与您的表架构进行比较。其中一个调用应该不匹配。

映射模板日志中的“fieldInError”布尔字段指示特定路径的解析是否成功,因此您可以内省失败的路径。

【讨论】:

以上是关于在 aws appsync 解析器中添加额外字段的主要内容,如果未能解决你的问题,请参考以下文章

未找到字段的值 - AppSync AWS

AWS Appsync 一个 dynamodb 解析器中的多个 dynamodb 请求

解析器中的 AppSync GraphQL 变异服务器逻辑

AWS AppSync GraphQL 输入验证 - 忽略额外字段?

AWS AppSync Lambda 解析器字段

Aws Appsync 解析器:如何创建解析器以更新列表映射 (DynaMoDB) 中的项目