我使用https://docs.amplify.aws/start/getting-started/data-model/q/integration/angular/ 上的教程使用 Angular 和 Amplify 創建了一個完整的堆疊應用程式。前端通過觸發 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 函式來完成處理檔案的繁重作業,并向客戶端回傳 201 ' 事件發生)。
第二個 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 控制臺等中沒有錯誤訊息。唯一不起作用的是在我有代碼的地方觸發了 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
}
uj5u.com熱心網友回復:
你有沒有機會啟用DataStore?如果您有,那么它會向您的所有模型添加一個 _version 欄位(類似于您提到的 updateAt 欄位)。在 GraphQL 中進行任何更新時,您必須通過該 _version 欄位以及為該模型存盤的最后一個好值,否則更新將失敗(因此不會觸發您的更新事件)。但是這個理論只有在你真正啟用了 DataStore 時才成立:)
uj5u.com熱心網友回復:
我早該知道這會是一件愚蠢的事情。
mutation = 'mutation update {updateDestinationFile(input: ' destination_file ') { filename status }}'
owner回傳集中缺少上面的行。由于我的架構包括:
type DestinationFile @model @auth(rules: [{ allow: owner }])
我必須回傳owner或更新訂閱永遠不會看到它。
mutation = 'mutation update {updateDestinationFile(input: ' destination_file ') { filename status owner }}
以上有效??。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/385198.html
