Skip to content

Commit 1efbcbc

Browse files
docs: WebSocket subscriptions for AppSync (#163)
Co-authored-by: Mathieu Cloutier <79954947+cloutierMat@users.noreply.github.com>
1 parent 06a2a58 commit 1efbcbc

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed

src/content/docs/aws/services/appsync.mdx

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,141 @@ Pipeline resolvers, on the other hand, invoke AppSync functions that wraps the A
204204
Unit resolvers are written in the Velocity templating language (VTL), while pipeline resolvers can be written in either VTL or JavaScript.
205205

206206

207+
### WebSocket Subscriptions
208+
209+
LocalStack supports real-time GraphQL subscriptions over WebSocket for AWS AppSync APIs.
210+
211+
Clients can subscribe to mutation-triggered events and receive updates in real time via the AppSync WebSocket endpoint. LocalStack supports the GraphQL `@aws_subscribe` directive, and core subscription message flow. Use this feature to power live updates in apps such as chat, dashboards, or collaborative editors. There's no need to poll for changes.
212+
213+
You can set up a GraphQL subscription in your schema, connect to the WebSocket endpoint, and receive live updates triggered by a mutation.
214+
215+
#### 1. Extend Your GraphQL Schema
216+
217+
First, ensure your schema includes a `subscription` type. Use the `@aws_subscribe` directive to link each subscription to a corresponding mutation.
218+
219+
```graphql
220+
type Message {
221+
id: ID!
222+
content: String!
223+
}
224+
225+
type Mutation {
226+
postMessage(id: ID!, content: String!): Message!
227+
}
228+
229+
type Subscription {
230+
onMessagePosted: Message
231+
@aws_subscribe(mutations: ["postMessage"])
232+
}
233+
234+
schema {
235+
query: Query
236+
mutation: Mutation
237+
subscription: Subscription
238+
}
239+
```
240+
241+
#### 2. Connect to the WebSocket Endpoint
242+
243+
LocalStack exposes a WebSocket endpoint for each GraphQL API:
244+
245+
```json
246+
"REALTIME": "ws://localhost:4510/graphql/<api-id>"
247+
```
248+
249+
Use a WebSocket client like `wscat` to connect:
250+
251+
```bash
252+
npm install -g wscat
253+
254+
export API_ID=<your-api-id>
255+
256+
wscat \
257+
-s "graphql-ws" \
258+
-c "ws://localhost:4510/graphql/$API_ID"
259+
```
260+
261+
#### 3. Initialize the WebSocket Connection
262+
263+
After connecting, send a `connection_init` message:
264+
265+
```json
266+
{ "type": "connection_init" }
267+
```
268+
269+
You should receive a `connection_ack` in response.
270+
271+
#### 4. Start a Subscription
272+
273+
Use a `start` message to register your subscription:
274+
275+
```json
276+
{
277+
"id": "1",
278+
"type": "start",
279+
"payload": {
280+
"data": "{\"query\":\"subscription { onMessagePosted { id content } }\"}"
281+
}
282+
}
283+
```
284+
285+
#### 5. Trigger the Subscription
286+
287+
Now, trigger the matching mutation:
288+
289+
```bash
290+
curl -X POST http://${API_ID}.appsync-api.localhost.localstack.cloud:4566/graphql \
291+
-H "content-type: application/json" \
292+
-H "x-api-key: ${API_KEY}" \
293+
-d '{"query": "mutation { postMessage(id: \"1\", content: \"Hello world!\") { id content } }" }'
294+
```
295+
296+
You should see a live message from the WebSocket server like:
297+
298+
```json title="Output"
299+
{
300+
"type": "data",
301+
"id": "1",
302+
"payload": {
303+
"data": {
304+
"onMessagePosted": {
305+
"id": "1",
306+
"content": "Hello world!"
307+
}
308+
}
309+
}
310+
}
311+
```
312+
313+
#### 6. Stop the Subscription
314+
315+
To unregister, send a `stop` message:
316+
317+
```json
318+
{ "type": "stop", "id": "1" }
319+
```
320+
321+
You'll receive a `complete` message when successful.
322+
323+
### Supported WebSocket Message Types
324+
325+
LocalStack supports the following WebSocket message types:
326+
327+
| Type | Description |
328+
| ----------------- | ----------------------------------------------- |
329+
| `connection_init` | Client initiates connection |
330+
| `connection_ack` | Server acknowledges the connection |
331+
| `start` | Starts a subscription |
332+
| `start_ack` | Acknowledges a successful subscription |
333+
| `data` | Sends a message when a matching mutation occurs |
334+
| `stop` | Client unsubscribes from a subscription |
335+
| `complete` | Server confirms unsubscription |
336+
337+
207338
### Configuring GraphQL endpoints
208339

209340
There are three configurable strategies that govern how GraphQL API endpoints are created.
341+
210342
The strategy can be configured via the `GRAPHQL_ENDPOINT_STRATEGY` environment variable.
211343

212344
| Value | Format | Description |
@@ -216,6 +348,24 @@ The strategy can be configured via the `GRAPHQL_ENDPOINT_STRATEGY` environment v
216348
| `legacy` | `localhost:4566/graphql/<api-id>` | This strategy represents the old endpoint format, which is currently the default but will eventually be phased out. |
217349

218350

351+
In addition to the GraphQL HTTP endpoint, each AppSync API also provides a WebSocket endpoint for GraphQL subscriptions.
352+
353+
The WebSocket server runs on a separate port that may change between deployments. To ensure correct connectivity, always use the `REALTIME` URL returned in the `uris` field of the `create-graphql-api` or `get-graphql-api` responses.
354+
355+
Example:
356+
357+
```json
358+
"uris": {
359+
"GRAPHQL": "http://localhost:4566/graphql/<api-id>",
360+
"REALTIME": "ws://localhost:4510/graphql/<api-id>"
361+
}
362+
```
363+
364+
:::note
365+
The `REALTIME` endpoint will ignore the `GRAPHQL_ENDPOINT_STRATEGY` and always use the `legacy` strategy.
366+
:::
367+
368+
219369
### GraphQL Resource Browser
220370

221371
The LocalStack Web Application provides a Resource Browser for managing AppSync APIs, Data Sources, Schema, Query, Types, Resolvers, Functions and API keys.

0 commit comments

Comments
 (0)