AWS Amplify AppSync 订阅无法正常工作
AWS Amplify AppSync Subscription not working correctly
我编写了一个使用 AWS Amplify CLI / AppSync 订阅数据库更改的小型应用程序。所有放大 api 调用都完美地工作(突变、查询),但不幸的是观察者没有收到事件。我可以看到 MQTT 套接字定期接收二进制文件,但我无法获取更改的对象。
我配置了 Amplify 以供放大使用。我可以在调试器中看到 AppSyncProvider 已被初始化。还尝试了 API 和 PubSub,但没有任何区别。
const awsmobile = {
"aws_appsync_graphqlEndpoint": "https://[...].appsync-api.[...]/graphql",
"aws_appsync_region": "[...]",
"aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
};
Amplify.configure(awsmobile);
ngOnInit()
{
try {
this.apiService.OnUpdateA.subscribe(
{
next: (x) => {[...]},
error: (e) => {[...]},
complete: () => {[...]}
});
}
catch (error) {[...] }
}
***Schema***
type A
@model
@auth(rules: [
{allow: owner},
{allow: groups, groups: ["A"], operations: [create, update, read]},
{allow: groups, groups: ["B"], operations: [read]},
])
{
id: ID!
entry: AnotherType! @connection(name: "AnotherConnection")
[...]
}
OnUpdateAListener: Observable<
OnUpdateASubscription
> = API.graphql(
graphqlOperation(
`subscription OnUpdateA($owner: String) {
onUpdateA(owner: $owner) {
__typename
id
owner
[...]
}
}`
)
) as Observable<OnUpdateASubscription>;
有人有什么想法吗?
**Logs:**
{mqttConnections: Array(1), newSubscriptions: {…}, provider: Symbol(INTERNAL_AWS_APPSYNC_PUBSUB_PROVIDER)}
mqttConnections: Array(1)
0: {url: "wss://[...]-ats.iot.[...].amazonaws…[...]%3D%3D", topics: Array(2), client: "[...]"}
length: 1
__proto__: Array(0)
newSubscriptions:
onUpdate:
expireTime: 1573313050000
topic: "[....]/22tmaezjv5555h4o7yreu24f7u/onUpdate/1cd033bad555ba55555a20690d3e04e901145776d3b8d8ac95a0aea447b273c3"
__proto__: Object
__proto__: Object
provider: Symbol(INTERNAL_AWS_APPSYNC_PUBSUB_PROVIDER)
__proto__: Object
但是,不确定是否怀疑订阅对象没有队列?
Subscription {_observer: {…}, _queue: undefined, _state: "ready", _cleanup: ƒ}
_cleanup: ƒ ()
_observer:
next: (x) => {…}
__proto__: Object
_queue: ***undefined***
_state: "ready"
closed: (...)
__proto__: Object
非常感谢。
这是 AWS Amplify 订阅的一个工作示例:
import Amplify from 'aws-amplify';
import API from '@aws-amplify/api';
import PubSub from '@aws-amplify/pubsub';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
API.configure(awsconfig);
PubSub.configure(awsconfig);
// put above in root
// below is example
import { API, graphqlOperation } from 'aws-amplify';
var onAddNote = `subscription OnCreateNote {
onCreateNote {
id
patient {
id
organization {
id
}
}
}
}
`;
listenForNoteAdd() {
return API.graphql(graphqlOperation(onAddNote) ).subscribe({next: (noteData) => {
console.log("new note so reload consider reload")
let note = noteData.value.data.onCreateNote
console.log(JSON.stringify(note))
// now that you have indication of something happening
// do what you must next
}})
}
对于那些有同样行为的人。这是因为我在架构的 auth 部分拥有所有者。删除了 {allow: owner}
部分,订阅立即开始工作。
对于那些遇到这个错误的人,不要删除 {allow: owner}
。允许所有者确保只有通过 Cognito 用户池身份验证的用户才能 运行 查询、变更等
看起来 OP 正在使用 amplify codegen 来生成他的 API 服务,如果你看监听器有所有者的参数。它是可选的,但如果您的@auth 是 {allow: owner}
,则它是必需的。
附加说明:不确定他是否使用了存储在其数据存储区中的正确所有者字段。如果尚未创建所有者字段(或指定不同的字段),它将创建一个具有唯一 uuid 的字段。所以他可能路过错误的所有者或 none。
运行 获取所有者的简单调用...
export const GetOwner = async (id: string): Promise<GetOwnerQuery> => {
const statement = `query GetAppData($id: ID!) {
getAppData(id: $id) {
owner
}
}`;
const gqlAPIServiceArguments: any = {
id,
};
const response = (await API.graphql(graphqlOperation(statement, gqlAPIServiceArguments))) as any;
return <GetOwnerQuery>response.data.getAppData;
};
...并在您的订阅中传递它。
const { owner } = await GetOwner(id);
if (owner) {
this.apiUpdateListener$ = this.api.OnUpdateAppDataListener(owner).subscribe((data) => {
console.log('api update listener ===> ', data);
});
}
我在使用 GraphQL 时遇到了同样的问题。问题是:我们必须 return Owner 进行突变响应,以便让 Subscription 知道将此事件发送给谁。
删除 {allow: owner}
确实对我有用,但这不是正确的方法,因为我们需要它才能拥有基于所有者的数据访问权限。
所以我找到的正确方法是:
如果订阅是:
subscription MySubscription {
onCreateuser(owner: "$userName") {
id
name
number
}
}
突变应该是:
mutation MyMutation {
createUser(input: {name: "xyz", id: "user123", number: "1234567890"}) {
id
name
number
owner
}
}
我们必须return突变响应的所有者才能获得对该事件的订阅以及与突变响应相同的所有其他属性。
我编写了一个使用 AWS Amplify CLI / AppSync 订阅数据库更改的小型应用程序。所有放大 api 调用都完美地工作(突变、查询),但不幸的是观察者没有收到事件。我可以看到 MQTT 套接字定期接收二进制文件,但我无法获取更改的对象。
我配置了 Amplify 以供放大使用。我可以在调试器中看到 AppSyncProvider 已被初始化。还尝试了 API 和 PubSub,但没有任何区别。
const awsmobile = {
"aws_appsync_graphqlEndpoint": "https://[...].appsync-api.[...]/graphql",
"aws_appsync_region": "[...]",
"aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
};
Amplify.configure(awsmobile);
ngOnInit()
{
try {
this.apiService.OnUpdateA.subscribe(
{
next: (x) => {[...]},
error: (e) => {[...]},
complete: () => {[...]}
});
}
catch (error) {[...] }
}
***Schema***
type A
@model
@auth(rules: [
{allow: owner},
{allow: groups, groups: ["A"], operations: [create, update, read]},
{allow: groups, groups: ["B"], operations: [read]},
])
{
id: ID!
entry: AnotherType! @connection(name: "AnotherConnection")
[...]
}
OnUpdateAListener: Observable<
OnUpdateASubscription
> = API.graphql(
graphqlOperation(
`subscription OnUpdateA($owner: String) {
onUpdateA(owner: $owner) {
__typename
id
owner
[...]
}
}`
)
) as Observable<OnUpdateASubscription>;
有人有什么想法吗?
**Logs:**
{mqttConnections: Array(1), newSubscriptions: {…}, provider: Symbol(INTERNAL_AWS_APPSYNC_PUBSUB_PROVIDER)}
mqttConnections: Array(1)
0: {url: "wss://[...]-ats.iot.[...].amazonaws…[...]%3D%3D", topics: Array(2), client: "[...]"}
length: 1
__proto__: Array(0)
newSubscriptions:
onUpdate:
expireTime: 1573313050000
topic: "[....]/22tmaezjv5555h4o7yreu24f7u/onUpdate/1cd033bad555ba55555a20690d3e04e901145776d3b8d8ac95a0aea447b273c3"
__proto__: Object
__proto__: Object
provider: Symbol(INTERNAL_AWS_APPSYNC_PUBSUB_PROVIDER)
__proto__: Object
但是,不确定是否怀疑订阅对象没有队列?
Subscription {_observer: {…}, _queue: undefined, _state: "ready", _cleanup: ƒ}
_cleanup: ƒ ()
_observer:
next: (x) => {…}
__proto__: Object
_queue: ***undefined***
_state: "ready"
closed: (...)
__proto__: Object
非常感谢。
这是 AWS Amplify 订阅的一个工作示例:
import Amplify from 'aws-amplify';
import API from '@aws-amplify/api';
import PubSub from '@aws-amplify/pubsub';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
API.configure(awsconfig);
PubSub.configure(awsconfig);
// put above in root
// below is example
import { API, graphqlOperation } from 'aws-amplify';
var onAddNote = `subscription OnCreateNote {
onCreateNote {
id
patient {
id
organization {
id
}
}
}
}
`;
listenForNoteAdd() {
return API.graphql(graphqlOperation(onAddNote) ).subscribe({next: (noteData) => {
console.log("new note so reload consider reload")
let note = noteData.value.data.onCreateNote
console.log(JSON.stringify(note))
// now that you have indication of something happening
// do what you must next
}})
}
对于那些有同样行为的人。这是因为我在架构的 auth 部分拥有所有者。删除了 {allow: owner}
部分,订阅立即开始工作。
对于那些遇到这个错误的人,不要删除 {allow: owner}
。允许所有者确保只有通过 Cognito 用户池身份验证的用户才能 运行 查询、变更等
看起来 OP 正在使用 amplify codegen 来生成他的 API 服务,如果你看监听器有所有者的参数。它是可选的,但如果您的@auth 是 {allow: owner}
,则它是必需的。
附加说明:不确定他是否使用了存储在其数据存储区中的正确所有者字段。如果尚未创建所有者字段(或指定不同的字段),它将创建一个具有唯一 uuid 的字段。所以他可能路过错误的所有者或 none。
运行 获取所有者的简单调用...
export const GetOwner = async (id: string): Promise<GetOwnerQuery> => {
const statement = `query GetAppData($id: ID!) {
getAppData(id: $id) {
owner
}
}`;
const gqlAPIServiceArguments: any = {
id,
};
const response = (await API.graphql(graphqlOperation(statement, gqlAPIServiceArguments))) as any;
return <GetOwnerQuery>response.data.getAppData;
};
...并在您的订阅中传递它。
const { owner } = await GetOwner(id);
if (owner) {
this.apiUpdateListener$ = this.api.OnUpdateAppDataListener(owner).subscribe((data) => {
console.log('api update listener ===> ', data);
});
}
我在使用 GraphQL 时遇到了同样的问题。问题是:我们必须 return Owner 进行突变响应,以便让 Subscription 知道将此事件发送给谁。
删除 {allow: owner}
确实对我有用,但这不是正确的方法,因为我们需要它才能拥有基于所有者的数据访问权限。
所以我找到的正确方法是:
如果订阅是:
subscription MySubscription {
onCreateuser(owner: "$userName") {
id
name
number
}
}
突变应该是:
mutation MyMutation {
createUser(input: {name: "xyz", id: "user123", number: "1234567890"}) {
id
name
number
owner
}
}
我们必须return突变响应的所有者才能获得对该事件的订阅以及与突变响应相同的所有其他属性。