aws-amplify / aws-amplify/docs

Appsync GraphQL from node server - example needed for websocket subscription implementation

Open
#5,065 3 comments 1 reaction 0 assignees View on GitHub
amplify/data p4 theme:data-subscriptions
Dominant language
MDX
Stars
506
Forks
1.1k
Avg merge
3h 14m
Merged PRs (30d)
1

Description

**Describe the content issue**:
The AWS Amplify docs describe how to connect to amplify from a node server, for example, if you are restricted to using IAM auth. While the nodejs code sample is helpful, there's no example for how to establish a graphql websocket connection for a subscription to appsync.

I have scoured the internet the past few days and cannot find any good documentation or examples of how to do this.
I can share what _didn't_ work - I have a couple of attempts based on what amplify _does_ share, but unfortunately my approach always returns a nondescript 400 "network" error. I will include a code snippet for reference, but I am really looking for clear documentation.

Thanks!

**URL page where content issue is**: https://docs.amplify.aws/lib/graphqlapi/graphql-from-nodejs/q/platform/js/

Erroneous reference code (based off the amplify site):

```
function establishWsConnection() {
const GRAPHQL_HOST = 'pretty-url.domain.com'
let ws: WebSocket = undefined;
let signedHeaders: any = undefined;

const signer = new SignatureV4({
credentials: provideLocalIdentity,
region: this.AWS_REGION,
service: 'appsync',
sha256: Sha256,
});

const requestToBeSigned: HttpRequest = new HttpRequest({
method: 'POST',
hostname: GRAPHQL_HOST,
path: '/graphql/connect',
protocol: 'https:',
headers: {
'content-type': 'application/json; charset=UTF-8',
'accept': 'application/json, text/javascript',
'content-encoding': 'amz-1.0',
host: GRAPHQL_HOST, // compulsory
},
});

const signed = await signer.sign(requestToBeSigned);

const api_header = signed.headers;
signedHeaders = api_header;

const payload = {};

const base64_api_header = Buffer.from(JSON.stringify(api_header)).toString('base64');
const base64_payload = Buffer.from(JSON.stringify(payload)).toString('base64');
const appsync_url = `${this.websocketConnectionString}?header=${base64_api_header}&payload=${base64_payload}`;

ws = new WebSocket(appsync_url, ['graphql-ws']);

/**
* Send request over websocket
*/
const _send = (obj) => {
ws.send(JSON.stringify(obj));
};

let initializingMode = true;

ws.onopen = () => {
_send({ type: 'connection_init' });
};

ws.onerror = err => {
console.error('err', err.message, );
};

ws.onmessage = (e) => {
const data = JSON.parse(e.data.toString());

if (initializingMode) {
if (data.type == 'connection_ack') {
// Acknowledge came, so we can start subscribing

const query = {
query: `
subscription MySubscription {
onCreate(id: 123) {
name,
email,
id
}
}`,
};

const queryStr = JSON.stringify(query);

_send({
id: '987876988798611113', // should be uuid?
type: 'start',
payload: {
data: queryStr,
extensions: {
authorization: {
host: GRAPHQL_HOST,
...signedHeaders,
},
},
},
});
}

initializingMode = false;
return;
}
};
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the Node.js GraphQL documentation page linked in the issue and compare its existing IAM-auth example with the provided websocket subscription attempt. Document a working AppSync GraphQL websocket subscription flow for a Node server, including the authentication details needed to avoid the reported 400 network error.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, graphql, javascript, node.js
Domain
api, documentation
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.