Graphql 放大+应用同步不突变对象

Graphql 放大+应用同步不突变对象,graphql,apollo,react-apollo,aws-amplify,aws-appsync,Graphql,Apollo,React Apollo,Aws Amplify,Aws Appsync,我正在尝试使用Amplify+AppSync/GraphQL来设置一个应用程序,但之前我对它一无所知,但现在我面临着太多的问题,我怀疑这是否是一个好的决定 我通过Amplify添加了一个AppSync API 这些查询目前运行良好,但是,我很难让这些突变生效,更糟糕的是,它们没有给我任何错误 我的数据库模式的重要部分如下所示: type Mutation { updateVideoOnDemand(input: UpdateVideoOnDemandInput!): VideoOnDem

我正在尝试使用Amplify+AppSync/GraphQL来设置一个应用程序,但之前我对它一无所知,但现在我面临着太多的问题,我怀疑这是否是一个好的决定

我通过Amplify添加了一个AppSync API

这些查询目前运行良好,但是,我很难让这些突变生效,更糟糕的是,它们没有给我任何错误

我的数据库模式的重要部分如下所示:

type Mutation {
    updateVideoOnDemand(input: UpdateVideoOnDemandInput!): VideoOnDemand
}

type ScriptRow {
    loop: Int
    timeStart: Int
    character: String
    text: String
    guessed: Boolean
}

input ScriptRowInput {
    loop: Int
    timeStart: Int
    character: String
    text: String
    guessed: Boolean
}

input UpdateVideoOnDemandInput {
    guid: String!
    thumbNailUrl: [String]
    startTime: String
    workflowStatus: String
    srcVideo: String
    hlsUrl: String
    dashUrl: String
    scriptUrl: String
    mp4Urls: [String]
    transcriptUri: String
    isLoadingLoops: Boolean
    documentKey: String
    initialOffset: Int
    videoOffset: Int
    scriptRows: [ScriptRowInput!]
}

type VideoOnDemand {
    guid: String!
    thumbNailUrl: [String]
    startTime: String
    workflowStatus: String
    srcVideo: String
    hlsUrl: String
    dashUrl: String
    scriptUrl: String
    mp4Urls: [String]
    transcriptUri: String
    isLoadingLoops: Boolean
    documentKey: String
    initialOffset: Int
    videoOffset: Int
    scriptRows: [ScriptRow]
}
然后,我使用Amplify codegen工具生成了本地代码 哪个看起来不错

export const updateVideoOnDemand = `mutation UpdateVideoOnDemand($input: UpdateVideoOnDemandInput!) {
  updateVideoOnDemand(input: $input) {
    guid
    thumbNailUrl
    startTime
    workflowStatus
    srcVideo
    hlsUrl
    dashUrl
    scriptUrl
    mp4Urls
    transcriptUri
    isLoadingLoops
    documentKey
    initialOffset
    videoOffset
    scriptRows {
      loop
      timeStart
      character
      text
      guessed
    }
  }
}
`;
首先,我尝试使用简单的AWSAPI.GraphQL

        API.graphql(graphqlOperation(mutations.updateVideoOnDemand, {
          input: {
            guid: video.guid,
            initialOffset: values.initial_offset,
            videoOffset: values.video_offset,
            workflowStatus: 'Test',
            isLoadingLoops: true,
            scriptRows: rows,
          }
        })).then(
          updatedVideo => {
            message.success('Saved');
          }
        ).catch(err => message.error('Error saving data: ' + err))

变异的映射解析程序:

{
  "version": "2017-02-28",
  "operation": "UpdateItem",
  "key": {
    "guid": $util.dynamodb.toDynamoDBJson($ctx.args.input.guid),
  },

  ## Set up some space to keep track of things we're updating **
  #set( $expNames  = {} )
  #set( $expValues = {} )
  #set( $expSet = {} )
  #set( $expAdd = {} )
  #set( $expRemove = [] )

  ## Iterate through each argument, skipping keys **
  #foreach( $entry in $util.map.copyAndRemoveAllKeys($ctx.args.input, ["guid"]).entrySet() )
    #if( $util.isNull($entry.value) )
      ## If the argument is set to "null", then remove that attribute from the item in DynamoDB **

      #set( $discard = ${expRemove.add("#${entry.key}")} )
      $!{expNames.put("#${entry.key}", "${entry.key}")}
    #else
      ## Otherwise set (or update) the attribute on the item in DynamoDB **

      $!{expSet.put("#${entry.key}", ":${entry.key}")}
      $!{expNames.put("#${entry.key}", "${entry.key}")}
      $!{expValues.put(":${entry.key}", $util.dynamodb.toDynamoDB($entry.value))}
    #end
  #end

  ## Start building the update expression, starting with attributes we're going to SET **
  #set( $expression = "" )
  #if( !${expSet.isEmpty()} )
    #set( $expression = "SET" )
    #foreach( $entry in $expSet.entrySet() )
      #set( $expression = "${expression} ${entry.key} = ${entry.value}" )
      #if ( $foreach.hasNext )
        #set( $expression = "${expression}," )
      #end
    #end
  #end

  ## Continue building the update expression, adding attributes we're going to ADD **
  #if( !${expAdd.isEmpty()} )
    #set( $expression = "${expression} ADD" )
    #foreach( $entry in $expAdd.entrySet() )
      #set( $expression = "${expression} ${entry.key} ${entry.value}" )
      #if ( $foreach.hasNext )
        #set( $expression = "${expression}," )
      #end
    #end
  #end

  ## Continue building the update expression, adding attributes we're going to REMOVE **
  #if( !${expRemove.isEmpty()} )
    #set( $expression = "${expression} REMOVE" )

    #foreach( $entry in $expRemove )
      #set( $expression = "${expression} ${entry}" )
      #if ( $foreach.hasNext )
        #set( $expression = "${expression}," )
      #end
    #end
  #end

  ## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
  "update": {
    "expression": "${expression}",
    #if( !${expNames.isEmpty()} )
      "expressionNames": $utils.toJson($expNames),
    #end
    #if( !${expValues.isEmpty()} )
      "expressionValues": $utils.toJson($expValues),
    #end
  },

  "condition": {
    "expression": "attribute_exists(#guid)",
    "expressionNames": {
      "#guid": "guid",
    },
  }
}
响应映射模板:

$util.toJson($context.result)
该命令似乎运行成功,我得到了更新的视频作为结果,我可以看到它的更新数据。。。但是,数据库端的某些字段没有更新。。。在这种情况下,字段isLoadingLoops和scriptRows不会更新。。。如果我重新加载页面,我会再次得到旧的结果,如果我直接在DynamoDB实例上检查,我也会看到前3项被更新,但其余的都没有

我已尝试将代码迁移到使用AWSAPSync客户端/Apollo。。。。但错误依然存在

知道是什么引起的吗

使现代化 有一件事我不确定它们是否是某个错误的指标:


当我转到AppSync控制台->查询,然后单击播放图标时,我只看到两个选项可供选择:createVideoOnDemand和listVideoOnDemand,我没有看到那里的更新,这可能表明存在问题?

看起来它与应用程序同步/放大解决冲突的方式有关。如果启用了数据存储,则冲突解决处于活动状态

在服务器端使用NodeJS中的GraphQL时,除了在客户端使用DataStore client外,您可能还需要此信息,例如lambda with IAM auth:

包括(u)版本号的作品。有道理

另见: 对于新创建的模型不工作,请更新GraphQL,请参阅注释:

不起作用示例:

工作示例:

请注意:

从AppSync控制台写入数据

数据存储主要是为开发人员设计的,不必关注 后端并允许您的应用程序代码和工作流创建 每件事然而,您将在一些用例中使用 AppSync控制台、Lambda函数或其他带外进程 要编写数据(如批处理操作或数据迁移),您可能需要 不使用数据存储客户端发送GraphQL操作

在这些情况下,GraphQL的选择集 突变包括模型的所有必填字段,包括: _lastChangedAt、_version和_已删除,以便数据存储客户端可以对这些更新作出反应。您还需要发送当前的 对象版本在变异输入参数中作为_版本,以便 服务可以据此采取行动。如果您不将此信息发送到 在全局同步过程中,客户端最终仍将迎头赶上, 但您不会看到对客户端数据存储的实时更新 存储库

一个例子是:

{
  "version": "2017-02-28",
  "operation": "UpdateItem",
  "key": {
    "guid": $util.dynamodb.toDynamoDBJson($ctx.args.input.guid),
  },

  ## Set up some space to keep track of things we're updating **
  #set( $expNames  = {} )
  #set( $expValues = {} )
  #set( $expSet = {} )
  #set( $expAdd = {} )
  #set( $expRemove = [] )

  ## Iterate through each argument, skipping keys **
  #foreach( $entry in $util.map.copyAndRemoveAllKeys($ctx.args.input, ["guid"]).entrySet() )
    #if( $util.isNull($entry.value) )
      ## If the argument is set to "null", then remove that attribute from the item in DynamoDB **

      #set( $discard = ${expRemove.add("#${entry.key}")} )
      $!{expNames.put("#${entry.key}", "${entry.key}")}
    #else
      ## Otherwise set (or update) the attribute on the item in DynamoDB **

      $!{expSet.put("#${entry.key}", ":${entry.key}")}
      $!{expNames.put("#${entry.key}", "${entry.key}")}
      $!{expValues.put(":${entry.key}", $util.dynamodb.toDynamoDB($entry.value))}
    #end
  #end

  ## Start building the update expression, starting with attributes we're going to SET **
  #set( $expression = "" )
  #if( !${expSet.isEmpty()} )
    #set( $expression = "SET" )
    #foreach( $entry in $expSet.entrySet() )
      #set( $expression = "${expression} ${entry.key} = ${entry.value}" )
      #if ( $foreach.hasNext )
        #set( $expression = "${expression}," )
      #end
    #end
  #end

  ## Continue building the update expression, adding attributes we're going to ADD **
  #if( !${expAdd.isEmpty()} )
    #set( $expression = "${expression} ADD" )
    #foreach( $entry in $expAdd.entrySet() )
      #set( $expression = "${expression} ${entry.key} ${entry.value}" )
      #if ( $foreach.hasNext )
        #set( $expression = "${expression}," )
      #end
    #end
  #end

  ## Continue building the update expression, adding attributes we're going to REMOVE **
  #if( !${expRemove.isEmpty()} )
    #set( $expression = "${expression} REMOVE" )

    #foreach( $entry in $expRemove )
      #set( $expression = "${expression} ${entry}" )
      #if ( $foreach.hasNext )
        #set( $expression = "${expression}," )
      #end
    #end
  #end

  ## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
  "update": {
    "expression": "${expression}",
    #if( !${expNames.isEmpty()} )
      "expressionNames": $utils.toJson($expNames),
    #end
    #if( !${expValues.isEmpty()} )
      "expressionValues": $utils.toJson($expValues),
    #end
  },

  "condition": {
    "expression": "attribute_exists(#guid)",
    "expressionNames": {
      "#guid": "guid",
    },
  }
}

您可以在API上共享该变异的映射模板吗?``变异帮助{UpdateVideoOnDeOnDemandInput:{guid:2,initialOffset:1,videoOffset:2,workflowStatus:Test,isLoadingLoops:true,scriptRows:[{loop:1 timeStart:2字符:测试文本:测试猜测:false}]{guid isLoadingLoops initialOffset videoOffset工作流状态脚本行{loop timeStart character text}}``@danielfranca更新变异是否显示在控制台的文档部分?单击播放图标时显示的选项取决于您在控制台编辑器中编写的查询,所以这不一定指向问题。但若文档部分中并没有更新变异,则表示您并没有推送已将最新的schema+解析程序加载到云中。如果您想将amplify项目发布到GitHub,我可以帮助您进一步排除故障,并在解决此问题后返回此处。在本例中,有一个DynamoDB触发器正在覆盖表上的更改。我遇到了此问题。在失败后,我通过AppSync direct触发了一个变异从Lambda或Angular更新。updateAssetinput:{id:b34d3aa3-fbc4-48b5-acba-af616001630f,description:AppSync}并且它不会更改描述字段。我可以设置新字段,但无法编辑现有字段。目前我还不清楚。