Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AppSync subscription support #1352

Closed
Sunac opened this issue Sep 26, 2020 · 18 comments · Fixed by #1389
Closed

AppSync subscription support #1352

Sunac opened this issue Sep 26, 2020 · 18 comments · Fixed by #1389
Milestone

Comments

@Sunac
Copy link

Sunac commented Sep 26, 2020

I think that more and more people use AppSync nowadays, so it would be great to support its subscription via Altair as well.

Tried to set it and finally when in the subscription URL is put wss but with AppSync endpoint and not with the realtime URL
I got some response but says Error during WebSocket handshake: Unexpected response code: 404

With the realtime URL receives: Both, the "header", and the "payload" query string parameters are missing

Also found this one #417 but seems it has been closed with no solution.
Am I doing something wrong or it's not supported yet?

@welcome
Copy link

welcome bot commented Sep 26, 2020

👋🏾Thanks for opening your first issue here! Be sure to follow the issue template! ✌🏾

@imolorhe
Copy link
Collaborator

imolorhe commented Oct 4, 2020

Hey @Sunac, do you have (or know about) a publicly available graphql server using aws appsync that I could use for testing the implementation for this?

@imolorhe
Copy link
Collaborator

A branch has been created with changes that could potentially resolve this issue. However, there isn't a proper appsync setup to use to test that the implementation works as expected. If you have an app sync implementation that can be used, that would help move this along.

@Sunac
Copy link
Author

Sunac commented Oct 14, 2020

Thanks @imolorhe !! Unfortunatelly, this project is not publicly available but will try to get some that could be used.

@imolorhe
Copy link
Collaborator

imolorhe commented Nov 8, 2020

@Sunac I've deployed the changes with AppSync integration here: https://s18767-altair-imolorhe.surge.sh/

Please test the changes and let me know if it works.

A beautiful feature-rich GraphQL Client IDE for all platforms. Available for MacOS, Windows, Linux, Chrome, Firefox. Enables you interact with any GraphQL server you are authorized to access from any platform you are on. Much like Postman for GraphQL, you can easily test and optimize your GraphQL implementations. You also have several features to make your GraphQL development process much easier including subscriptions, query scaffolding, formatting, multiple languages, themes, and many more.

@joseph-so
Copy link
Contributor

joseph-so commented Nov 11, 2020

@imolorhe I am looking for something like that. I have tried to test your integration, but it returns

An error occurred in subscription.
Error: can't access property "url", t is undefined 

I am trying to connect mine one which is using JWT

@imolorhe
Copy link
Collaborator

@joseph-so nice that you're testing it. I need it. Could you provide more of the error stack?

@joseph-so
Copy link
Contributor

joseph-so commented Nov 11, 2020

@imolorhe ,
I am using the Firefox developer edition. The application is using JWT for the authentication

An error occurred starting the subscription. TypeError: can't access property "url", t is undefined
    n https://s18767-altair-imolorhe.surge.sh/main.js:1
    createSubscriptionHandshakeLink https://s18767-altair-imolorhe.surge.sh/main.js:1
    execute https://s18767-altair-imolorhe.surge.sh/main.js:1
    e/this.startSubscription$< https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    notifyNext https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    notifyNext https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    r https://s18767-altair-imolorhe.surge.sh/main.js:1
    _trySubscribe https://s18767-altair-imolorhe.surge.sh/main.js:1
    subscribe https://s18767-altair-imolorhe.surge.sh/main.js:1
    a https://s18767-altair-imolorhe.surge.sh/main.js:1
    _trySubscribe https://s18767-altair-imolorhe.surge.sh/main.js:1
    subscribe https://s18767-altair-imolorhe.surge.sh/main.js:1
    a https://s18767-altair-imolorhe.surge.sh/main.js:1
    _innerSub https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    r https://s18767-altair-imolorhe.surge.sh/main.js:1
    _trySubscribe https://s18767-altair-imolorhe.surge.sh/main.js:1
    subscribe https://s18767-altair-imolorhe.surge.sh/main.js:1
    call https://s18767-altair-imolorhe.surge.sh/main.js:1
    subscribe https://s18767-altair-imolorhe.surge.sh/main.js:1
    a https://s18767-altair-imolorhe.surge.sh/main.js:1
    _innerSub https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _tryProject https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    d https://s18767-altair-imolorhe.surge.sh/main.js:1
    __tryOrUnsub https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _tryNext https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    observe https://s18767-altair-imolorhe.surge.sh/main.js:1
    dispatch https://s18767-altair-imolorhe.surge.sh/main.js:1
    _execute https://s18767-altair-imolorhe.surge.sh/main.js:1
    execute https://s18767-altair-imolorhe.surge.sh/main.js:1
    flush https://s18767-altair-imolorhe.surge.sh/main.js:1
    schedule https://s18767-altair-imolorhe.surge.sh/main.js:1
    schedule https://s18767-altair-imolorhe.surge.sh/main.js:1
    schedule https://s18767-altair-imolorhe.surge.sh/main.js:1
    scheduleMessage https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    notifyNext https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    notifyNext https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    dispatch https://s18767-altair-imolorhe.surge.sh/main.js:1
    sendRequest https://s18767-altair-imolorhe.surge.sh/main.js:1
    template https://s18767-altair-imolorhe.surge.sh/main.js:1
    ba https://s18767-altair-imolorhe.surge.sh/main.js:1
    i https://s18767-altair-imolorhe.surge.sh/main.js:1
    o https://s18767-altair-imolorhe.surge.sh/main.js:1
    __tryOrUnsub https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    _next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    next https://s18767-altair-imolorhe.surge.sh/main.js:1
    emit https://s18767-altair-imolorhe.surge.sh/main.js:1
    DR https://s18767-altair-imolorhe.surge.sh/main.js:1
    ba https://s18767-altair-imolorhe.surge.sh/main.js:1
    i https://s18767-altair-imolorhe.surge.sh/main.js:1
    O https://s18767-altair-imolorhe.surge.sh/main.js:1
    invokeTask https://s18767-altair-imolorhe.surge.sh/polyfills.js:1
    onInvokeTask https://s18767-altair-imolorhe.surge.sh/main.js:1
    invokeTask https://s18767-altair-imolorhe.surge.sh/polyfills.js:1
    runTask https://s18767-altair-imolorhe.surge.sh/polyfills.js:1
    invokeTask https://s18767-altair-imolorhe.surge.sh/polyfills.js:1
    p https://s18767-altair-imolorhe.surge.sh/polyfills.js:1
    h https://s18767-altair-imolorhe.surge.sh/polyfills.js:1
main.js:1:2138721

I have followed https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html to get up the authentication header as

{
    "Authorization":"<JWT_TOKEN>",
    "host":"<application_url>"
}

I have put the above JSON into the Collection parameters in the Subscription URL

I have also set up the corresponding in the HTTP Header, so I can confirm the value is correct (I can get the Query and the Schema Document working)

P.S. I am looking for a simple way to confirm the AppSync developed by my colleague is correct before I start to write my own code.

Real-time WebSocket Client Set-up

@imolorhe
Copy link
Collaborator

imolorhe commented Nov 11, 2020

@joseph-so For the appsync subscription, I'm making use of https://github.com/awslabs/aws-mobile-appsync-sdk-js

You should only need to set the connection parameters with something like this:

{
    "aws_project_region": "us-west-2",
    "aws_appsync_graphqlEndpoint": "https://<id>.appsync-api.us-west-2.amazonaws.com/graphql",
    "aws_appsync_region": "us-west-2",
    "aws_appsync_authenticationType": "API_KEY",
    "aws_appsync_apiKey": "<api-key>"
}

.. and provide the same graphql endpoint as the URL in Altair and the subscription URL as well. You shouldn't need to set any headers. You should have the URLs as https:// as well, and not wss://

If it's possible, you could also checkout the simolorhe/implement-app-sync-subscription-provider branch locally and run Altair locally (from packages/altair-app). That would yield better error stacks that would be better to debug with. You could also end up debugging yourself.

GitHub
JavaScript library files for Offline, Sync, Sigv4. includes support for React Native - awslabs/aws-mobile-appsync-sdk-js

@joseph-so
Copy link
Contributor

joseph-so commented Nov 11, 2020

@imolorhe
Thanks a lot for your reply. However, our AppSync is implemented with the OpenID Connect, which cannot use API-KEY
(This will be useful if we need to test with the 3rd party API)

@imolorhe
Copy link
Collaborator

I don't think it only works with the API_KEY authentication type. What I'm just saying is that the data you pass in the connection parameters should be a valid aws export config

@Sunac
Copy link
Author

Sunac commented Nov 17, 2020

@imolorhe YOU'RE THE BEST 🥇

Sorry, I was off for several days and spotted it today. Tested it and looks fine 👍
I'm finally able to use my fav Altair for AppSync subscription as well.
Thanks a lot!

@imolorhe
Copy link
Collaborator

Awesome! Thanks for confirming @Sunac! Was it straightforward to work with? Are there any things to take note of? Can you post a snapshot of the valid config you used (remove sensitive aspects replaced with dummy before posting)?

I'd need to add that to the docs and ensure things are working as expected (since I can't test or use it myself 😅 )

@Sunac
Copy link
Author

Sunac commented Nov 18, 2020

@imolorhe Thank you!
Sure, I'll share with you my try. Basically, I just did what you already mentioned here: #1352 (comment)

Screenshot from 2020-11-18 14-47-47
Screenshot from 2020-11-18 14-30-21

So, to start receiving subscriptions this was enough. Didn't try yet to optimize the config but this works fine :).

It could be mentioned that the client uses MQTT over WebSockets (checked network) as full mutation payload is received and not only the selection set from my subscription as you can see in the response. That could be useful.
More details could be found here: https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html

Real-Time data for AWS AppSync.

@imolorhe
Copy link
Collaborator

Thanks for sharing. I'll most likely be using these screenshots as-is in the docs as well 🙂

@imolorhe imolorhe linked a pull request Nov 21, 2020 that will close this issue
@imolorhe imolorhe modified the milestones: v2.6.0, v3.0.0 Nov 22, 2020
@imolorhe
Copy link
Collaborator

Now in v3.0.0

@joseph-so
Copy link
Contributor

I don't think it only works with the API_KEY authentication type. What I'm just saying is that the data you pass in the connection parameters should be a valid aws export config

Hi @imolorhe, I have spent sometimes to understand the code and found out that you have allowed apiKey to be passed but not the jwtToken. That is the reason why I got the authentication fail.

I have created a new issue and pull request for you to review. Thanks a lot

@imolorhe
Copy link
Collaborator

@joseph-so awesome! I'll take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants