Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Running a fresh Angular application with no other dependencies aside from [email protected]
and type definitions to get the package to work: @types/[email protected]
, @types/[email protected]
, and @types/[email protected]
.
I'm not sure if I missed anything here but when using the API module to subscribe to AppSync, subscription data is not received. I followed the documentation here: https://github.com/aws/aws-amplify/blob/master/docs/media/api_guide.md. Tried to do a basic subscription that prints to the console newly added users.
GraphQL Subscription:
'subscription AddedUser {
addedUser {
userID,
userFirstName,
userLastName
}
}';
Code:
const subscription = API.graphql(graphqlOperation(UserService.AddedUser)) as Observable<object>;
subscription.subscribe({
next: (eventData) => console.log(JSON.stringify(eventData))
});
I've already tried the same subscription on the AppSync console and can confirm that it does work. I just can't get it to work in the Angular application.
Plus the documentation guide is slightly off: queries and mutations are passed in the API.graphql()
function while subscriptions are passed in the API.graphqlSubscribe()
function. Though during my usage, there is no graphqlSubscribe()
available in the API module (at least not publicly available). What I did notice though is that the graphql()
function returns an object of type Promise<GraphQLResult>
or Observable<object>
(I should be using this for all operations, right?). A Promise object is returned when passing query/mutations while an Observable object is returned when passing subscriptions.
What is the expected behavior?
Subscriptions should receive data changes from mutations.
Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions?
Version: [email protected]
Browser: Chrome
OS: Windows 10
Hi @mg131, thanks for pointing out the docs error, as you correctly mention, API.graphqlSubscribe()
doesn't exist, the correct one for all GraphQL operations is API.graphql()
.
Regarding not receiving data, can you verify in your network tab of the developer tools that a network request to start the subscriptions handshake is made and that a websocket connection is opened?
Hey @manueliglesias, I took a look at the network tab and yes, a network request was sent.
Image of network request here (XHR tab):
https://imgur.com/Die7CTK
But it doesn't seem to create a websocket to the subscription.
Image of websockets in Chrome here (WS tab):
https://imgur.com/TJwR9I5
This is pretty much the only code I did for Amplify. Am I doing something wrong here? No results, no errors, nothing.
import { Component, OnInit } from '@angular/core';
import { API, graphqlOperation } from 'aws-amplify';
import { GraphQLResult } from 'aws-amplify/lib/API/types';
import * as Observable from 'zen-observable';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
private static UserSubscription: string = `subscription {
addedUser {
userID,
userFirstName,
userLastName
}
}`;
ngOnInit() {
const observable: Observable<object> = API.graphql(graphqlOperation(AppComponent.UserSubscription)) as Observable<object>;
observable.subscribe({
next: (value: object) => {
console.log(JSON.stringify(value));
},
error: (error: any) => {
console.log(JSON.stringify(error));
}
});
}
}
I was able to get subscriptions working by creating a new Angular application. This time the only dependencies are: [email protected]
and [email protected]
. The rest are Angular default packages. Results are now printed to the Chrome console when I execute mutations in AppSync console.
Here is an image of a websocket created by aws-appsync (WS tab):
https://imgur.com/OhjDQFO
Notes: Mutations and Queries do work in Amplify. I've already tested them.
Im facing the same issue with aws-amplify-react-native library. Queries works fine, but I cannot use subscriptions. When I try subscriptions in the AppSync console it works fine.
@mg131 @karlmosenbacher
I couldn't reproduce the issue you are seeing, I created a small codesandbox with working vanilla js code. I would suggest looking closely at how Amplify is being configured there.
The code assumes a schema from the sample API in the AppSync console, but shouldn't be too complex to adapt to yours.
Please let me know how it goes!
@manueliglesias thanks! I'll take a look
@manueliglesias Thanks for the code demonstration. I finally found the bug that ate up all my hours hahaha. And you're right, Amplify wasn't properly configured.
After looking at your code and wondering why mine doesn't work, I decided to dig the Amplify code. I started with the API.graphql
function and noticed that code splits here: calling _graphql
for Mutations/Queries and calling _graphqlSubscribe
for Subscriptions. Obviously, the problem lies in _graphqlSubscribe
, specifically in the switch-case statement. From here, you can see that the API module uses the PubSub module for GraphQL Subscriptions. From the looks of it, the PubSub.subscribe
function handles the creation of web sockets.
In the PubSub.subscribe
function, I found out that the _pluggables
object is empty leading to no provider for the subscription. After a bit of tracing, you can find that the _pluggables
object is initialized in PubSub.configure
. Then it hit me right here, what if the PubSub module wasn't configured properly. I took a look back at the codesandbox configuration of Amplify, followed the format, and bam! Subscriptions are now working! Now I look like an idiot ahaha.
Here is how I configured Amplify:
Amplify.configure({
Auth: {
identityPoolId: 'xxx',
region: 'xxx' ,
cookieStorage: {
domain: 'xxx',
path: 'xxx',
secure: true
}
},
API: {
aws_appsync_graphqlEndpoint: 'xxxx',
aws_appsync_region: 'xxxx',
aws_appsync_authenticationType: 'xxxx',
aws_appsync_apiKey: 'xxxx'
}
});
Note: This only configures the API module (and the Auth module based on my config). And as I mentioned above, the API module uses the PubSub module for Subscriptions (MQTT). The PubSub module needs to be configured.
So I changed my configuration to:
Amplify.configure({
Auth: {
identityPoolId: 'xxx',
region: 'xxx' ,
cookieStorage: {
domain: 'xxx',
path: 'xxx',
secure: true
}
},
aws_appsync_graphqlEndpoint: 'xxxx',
aws_appsync_region: 'xxxx',
aws_appsync_authenticationType: 'xxxx',
aws_appsync_apiKey: 'xxxx'
});
And now the Subscriptions work! (Oddly, this seems to configure both the API and PubSub module)
I spent so much time debugging the problem and I never even looked at the configuration. I mean why would you bother checking the configuration if Mutations/Queries work? You can pretty much guarantee that it was configured properly because they work in the first place!
TLDR:
In order for Amplify.API Subscriptions to work, write your AppSync configuration at the root of the object. Do not nest them in API configuration!
@karlmosenbacher You might wanna check your configuration.
Reopening so we can capture some of this in documentation. @mbahar fyi
Ok. I noted this one. Closing.
Most helpful comment
@manueliglesias Thanks for the code demonstration. I finally found the bug that ate up all my hours hahaha. And you're right, Amplify wasn't properly configured.
After looking at your code and wondering why mine doesn't work, I decided to dig the Amplify code. I started with the
API.graphql
function and noticed that code splits here: calling_graphql
for Mutations/Queries and calling_graphqlSubscribe
for Subscriptions. Obviously, the problem lies in_graphqlSubscribe
, specifically in the switch-case statement. From here, you can see that the API module uses the PubSub module for GraphQL Subscriptions. From the looks of it, thePubSub.subscribe
function handles the creation of web sockets.In the
PubSub.subscribe
function, I found out that the_pluggables
object is empty leading to no provider for the subscription. After a bit of tracing, you can find that the_pluggables
object is initialized inPubSub.configure
. Then it hit me right here, what if the PubSub module wasn't configured properly. I took a look back at the codesandbox configuration of Amplify, followed the format, and bam! Subscriptions are now working! Now I look like an idiot ahaha.Here is how I configured Amplify:
Note: This only configures the API module (and the Auth module based on my config). And as I mentioned above, the API module uses the PubSub module for Subscriptions (MQTT). The PubSub module needs to be configured.
So I changed my configuration to:
And now the Subscriptions work! (Oddly, this seems to configure both the API and PubSub module)
I spent so much time debugging the problem and I never even looked at the configuration. I mean why would you bother checking the configuration if Mutations/Queries work? You can pretty much guarantee that it was configured properly because they work in the first place!
TLDR:
In order for Amplify.API Subscriptions to work, write your AppSync configuration at the root of the object. Do not nest them in API configuration!
@karlmosenbacher You might wanna check your configuration.