AppSync onUpdate 订阅未由 python 请求触发 POST 到 GraphQL 端点

AppSync onUpdate subscription not triggered by python requests POST to GraphQL endpoint

我使用 Angular 创建了一个完整的堆栈应用程序,并使用 https://docs.amplify.aws/start/getting-started/data-model/q/integration/angular/ 中的教程进行了扩展。前端通过触发 onCreate 订阅的 AppSync 成功创建 GraphQL 条目,但从后端的 python lambda 函数更改该数据不会触发 onUpdate 订阅。

body.component.ts

  ngOnInit(): void {
        this.api.ListDestinationFiles().then((event) => {
          // do stuff here... (this works)
        });

        this.update_subscription = <Subscription>(
          this.api.OnUpdateDestinationFileListener(user.username).subscribe((event: any) => {
            // this never fires
            console.log('OnUpdate', event);
          }));
        this.create_subscription = <Subscription>(
          this.api.OnCreateDestinationFileListener(user.username).subscribe((event: any) => {
            // this does fire.
            console.log('OnCreate', event);
          }));
      })
  }

我的网页允许用户上传触发此功能的文件 body.component.ts:

  upload(): void {
    API.post(this.apiName, this.path, this.myInit)
      .then(response => {
        let keys = Object.keys(response['dest_file_urls']);
        this.graphql_api
          .CreateDestinationFile({
            filename: keys[0],
            signedURL: response['dest_file_urls'][keys[0]],
            status: 'Started'
          })
          .then((event) => {
            // this triggers successfully, and the item is indeed created
            console.log('item created', event);
          })

到目前为止一切都很好并且按预期工作。 API.post 将文件发送到 python lambda 函数,该函数将文件保存到 S3 存储桶,触发第二个 lambda 函数来完成处理文件的繁重工作,并且 returns 201给客户端(那是 'item created' 事件发生的时间)。

第二个 lambda 函数包含此代码:

destination_file = '{id: "' + str(gql_id) + '", filename: "' + d_filename + '", signedURL: "' + signedURL + '", status: "Finished"}'
mutation = 'mutation update {updateDestinationFile(input: ' + destination_file + ') { filename status }}'
response = session.request(url=endpoint, method='POST', headers=headers, json={'query': mutation})

AppSync POST 工作正常,数据正在后端更新,CloudWatch、Java 控制台等没有错误消息。唯一没有的是t 工作是触发 onUpdate 订阅,我有代码来更新网页,指示过程已完成。

我找到了各种关于为 AppSync 启用实时更新的文章和文档,其中包括添加或替换数据源类型为 NONE 的自动生成的解析器,以及进行各种传递,但这似乎是与最新版本的 AppSync 不再相关的遗留文档。我自动生成的更新解析器是一个 4 步管道处理身份验证、更新“updatedAt”字段等,并且在其中两个步骤中已经有了 NONE 数据源。

这是完整的架构,因为我有强烈的倾向,这是我需要以某种方式修改的内容,尽管它是自动生成的,我还没有找到明确的文档来在 schema.graphql 文件中进行修改.

input CreateDestinationFileInput {
    id: ID
    filename: String!
    signedURL: String
    status: String
}

input DeleteDestinationFileInput {
    id: ID!
}

type DestinationFile {
    id: ID!
    filename: String!
    signedURL: String
    status: String
    createdAt: AWSDateTime!
    updatedAt: AWSDateTime!
    owner: String
}

enum ModelAttributeTypes {
    binary
    binarySet
    bool
    list
    map
    number
    numberSet
    string
    stringSet
    _null
}

input ModelBooleanInput {
    ne: Boolean
    eq: Boolean
    attributeExists: Boolean
    attributeType: ModelAttributeTypes
}

input ModelDestinationFileConditionInput {
    filename: ModelStringInput
    signedURL: ModelStringInput
    status: ModelStringInput
    and: [ModelDestinationFileConditionInput]
    or: [ModelDestinationFileConditionInput]
    not: ModelDestinationFileConditionInput
}

type ModelDestinationFileConnection {
    items: [DestinationFile!]!
    nextToken: String
}

input ModelDestinationFileFilterInput {
    id: ModelIDInput
    filename: ModelStringInput
    signedURL: ModelStringInput
    status: ModelStringInput
    and: [ModelDestinationFileFilterInput]
    or: [ModelDestinationFileFilterInput]
    not: ModelDestinationFileFilterInput
}

input ModelFloatInput {
    ne: Float
    eq: Float
    le: Float
    lt: Float
    ge: Float
    gt: Float
    between: [Float]
    attributeExists: Boolean
    attributeType: ModelAttributeTypes
}

input ModelIDInput {
    ne: ID
    eq: ID
    le: ID
    lt: ID
    ge: ID
    gt: ID
    contains: ID
    notContains: ID
    between: [ID]
    beginsWith: ID
    attributeExists: Boolean
    attributeType: ModelAttributeTypes
    size: ModelSizeInput
}

input ModelIntInput {
    ne: Int
    eq: Int
    le: Int
    lt: Int
    ge: Int
    gt: Int
    between: [Int]
    attributeExists: Boolean
    attributeType: ModelAttributeTypes
}

input ModelSizeInput {
    ne: Int
    eq: Int
    le: Int
    lt: Int
    ge: Int
    gt: Int
    between: [Int]
}

enum ModelSortDirection {
    ASC
    DESC
}

input ModelStringInput {
    ne: String
    eq: String
    le: String
    lt: String
    ge: String
    gt: String
    contains: String
    notContains: String
    between: [String]
    beginsWith: String
    attributeExists: Boolean
    attributeType: ModelAttributeTypes
    size: ModelSizeInput
}

type Mutation {
    createDestinationFile(input: CreateDestinationFileInput!, condition: ModelDestinationFileConditionInput): DestinationFile
    updateDestinationFile(input: UpdateDestinationFileInput!, condition: ModelDestinationFileConditionInput): DestinationFile
    deleteDestinationFile(input: DeleteDestinationFileInput!, condition: ModelDestinationFileConditionInput): DestinationFile
}

type Query {
    getDestinationFile(id: ID!): DestinationFile
    listDestinationFiles(filter: ModelDestinationFileFilterInput, limit: Int, nextToken: String): ModelDestinationFileConnection
}

type Subscription {
    onCreateDestinationFile(owner: String): DestinationFile
        @aws_subscribe(mutations: ["createDestinationFile"])
    onUpdateDestinationFile(owner: String): DestinationFile
        @aws_subscribe(mutations: ["updateDestinationFile"])
    onDeleteDestinationFile(owner: String): DestinationFile
        @aws_subscribe(mutations: ["deleteDestinationFile"])
}

input UpdateDestinationFileInput {
    id: ID!
    filename: String
    signedURL: String
    status: String
}

这都是在 schema.graphql 文件中创建的:

type DestinationFile @model @auth(rules: [{ allow: owner }]) {
  id: ID!
  filename: String!
  signedURL: String
  status: String
}

您有没有启用 DataStore?如果你有那么它会为你所有的模型添加一个 _version 字段(类似于你提到的 updateAt 字段)。在 GraphQL 中进行任何更新时,您必须通过 _version 字段为该模型存储最后一个有效值,否则更新将失败(因此不会触发您的更新事件)。但这个理论只有在您实际启用了 DataStore 时才成立:)

我早该知道这会很傻。

mutation = 'mutation update {updateDestinationFile(input: ' + destination_file + ') { filename status }}'

return 集中缺少 owner 上面的行。由于我的模式包括:

type DestinationFile @model @auth(rules: [{ allow: owner }])

我必须 return owner 否则更新订阅永远看不到它。

mutation = 'mutation update {updateDestinationFile(input: ' + destination_file + ') { filename status owner }}

以上作品。