Altair: AppSync subscription support

Created on 26 Sep 2020  ·  16Comments  ·  Source: imolorhe/altair

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 https://github.com/imolorhe/altair/issues/417 but seems it has been closed with no solution.
Am I doing something wrong or it's not supported yet?

All 16 comments

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

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?

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.

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

@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.

@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

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

@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

@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

@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)

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

@imolorhe YOU'RE THE BEST :1st_place_medal:

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

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 😅 )

@imolorhe Thank you!
Sure, I'll share with you my try. Basically, I just did what you already mentioned here: https://github.com/imolorhe/altair/issues/1352#issuecomment-725375052

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.

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

Now in v3.0.0

Was this page helpful?
0 / 5 - 0 ratings