diff --git a/src/content/docs/aws/services/appsync.mdx b/src/content/docs/aws/services/appsync.mdx index 2c50a10a..71009212 100644 --- a/src/content/docs/aws/services/appsync.mdx +++ b/src/content/docs/aws/services/appsync.mdx @@ -204,9 +204,141 @@ Pipeline resolvers, on the other hand, invoke AppSync functions that wraps the A Unit resolvers are written in the Velocity templating language (VTL), while pipeline resolvers can be written in either VTL or JavaScript. +### WebSocket Subscriptions + +LocalStack supports real-time GraphQL subscriptions over WebSocket for AWS AppSync APIs. + +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. + +You can set up a GraphQL subscription in your schema, connect to the WebSocket endpoint, and receive live updates triggered by a mutation. + +#### 1. Extend Your GraphQL Schema + +First, ensure your schema includes a `subscription` type. Use the `@aws_subscribe` directive to link each subscription to a corresponding mutation. + +```graphql +type Message { + id: ID! + content: String! +} + +type Mutation { + postMessage(id: ID!, content: String!): Message! +} + +type Subscription { + onMessagePosted: Message + @aws_subscribe(mutations: ["postMessage"]) +} + +schema { + query: Query + mutation: Mutation + subscription: Subscription +} +``` + +#### 2. Connect to the WebSocket Endpoint + +LocalStack exposes a WebSocket endpoint for each GraphQL API: + +```json +"REALTIME": "ws://localhost:4510/graphql/" +``` + +Use a WebSocket client like `wscat` to connect: + +```bash +npm install -g wscat + +export API_ID= + +wscat \ + -s "graphql-ws" \ + -c "ws://localhost:4510/graphql/$API_ID" +``` + +#### 3. Initialize the WebSocket Connection + +After connecting, send a `connection_init` message: + +```json +{ "type": "connection_init" } +``` + +You should receive a `connection_ack` in response. + +#### 4. Start a Subscription + +Use a `start` message to register your subscription: + +```json +{ + "id": "1", + "type": "start", + "payload": { + "data": "{\"query\":\"subscription { onMessagePosted { id content } }\"}" + } +} +``` + +#### 5. Trigger the Subscription + +Now, trigger the matching mutation: + +```bash +curl -X POST http://${API_ID}.appsync-api.localhost.localstack.cloud:4566/graphql \ + -H "content-type: application/json" \ + -H "x-api-key: ${API_KEY}" \ + -d '{"query": "mutation { postMessage(id: \"1\", content: \"Hello world!\") { id content } }" }' +``` + +You should see a live message from the WebSocket server like: + +```json title="Output" +{ + "type": "data", + "id": "1", + "payload": { + "data": { + "onMessagePosted": { + "id": "1", + "content": "Hello world!" + } + } + } +} +``` + +#### 6. Stop the Subscription + +To unregister, send a `stop` message: + +```json +{ "type": "stop", "id": "1" } +``` + +You'll receive a `complete` message when successful. + +### Supported WebSocket Message Types + +LocalStack supports the following WebSocket message types: + +| Type | Description | +| ----------------- | ----------------------------------------------- | +| `connection_init` | Client initiates connection | +| `connection_ack` | Server acknowledges the connection | +| `start` | Starts a subscription | +| `start_ack` | Acknowledges a successful subscription | +| `data` | Sends a message when a matching mutation occurs | +| `stop` | Client unsubscribes from a subscription | +| `complete` | Server confirms unsubscription | + + ### Configuring GraphQL endpoints There are three configurable strategies that govern how GraphQL API endpoints are created. + The strategy can be configured via the `GRAPHQL_ENDPOINT_STRATEGY` environment variable. | Value | Format | Description | @@ -216,6 +348,24 @@ The strategy can be configured via the `GRAPHQL_ENDPOINT_STRATEGY` environment v | `legacy` | `localhost:4566/graphql/` | This strategy represents the old endpoint format, which is currently the default but will eventually be phased out. | +In addition to the GraphQL HTTP endpoint, each AppSync API also provides a WebSocket endpoint for GraphQL subscriptions. + +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. + +Example: + +```json +"uris": { + "GRAPHQL": "http://localhost:4566/graphql/", + "REALTIME": "ws://localhost:4510/graphql/" +} +``` + +:::note +The `REALTIME` endpoint will ignore the `GRAPHQL_ENDPOINT_STRATEGY` and always use the `legacy` strategy. +::: + + ### GraphQL Resource Browser The LocalStack Web Application provides a Resource Browser for managing AppSync APIs, Data Sources, Schema, Query, Types, Resolvers, Functions and API keys.