aws-amplify / aws-amplify/docs
Appsync GraphQL from node server - example needed for websocket subscription implementation
- 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
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