You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
New GraphQLWsLink for graphql-ws subscriptions library
Apollo Client currently contains `WebSocketLink` in
`@apollo/client/link/ws` which uses the `subscriptions-transport-ws`
library. That library is no longer actively maintained, and there is an
improved fork called `graphql-ws`.
The two libraries use different protocols so a different client link is
required for `graphql-ws`. (While the WebSocket protocol does allow for
subprotocol negotiation, neither server implementation supports this in
a practical way.)
This PR adds a new link `GraphQLWsLink` in
`@apollo/client/link/subscriptions`. Its constructor arguments are the
same as the `createClient` function in `graphql-ws` (or it can take a
`Client` object returned from that function), and you need to install
the optional peer dep `graphql-ws` instead of
`subscriptions-transport-ws`. Once you've created the link, it works
exactly like the old `WebSocketLink`.
This PR changes the main subscriptions doc page to mostly document the
new link, with an extra section at the bottom for the old link.
The core GraphQLWsLink code is based on MIT-licensed code from the
README of the graphql-ws repository.
Fixes#8345.
Part of apollographql/apollo-server#6058
description: Execute subscriptions (or other GraphQL operations) over WebSocket with the `graphql-ws` library
5
+
api_reference: true
6
+
---
7
+
8
+
> We recommend reading [Apollo Link overview](./introduction/) before learning about individual links.
9
+
10
+
The `GraphQLWsLink` is a [terminating link](./introduction/#the-terminating-link) that's used most commonly with GraphQL [subscriptions](../../data/subscriptions/) (which usually communicate over WebSocket), although you can send queries and mutations over WebSocket as well.
11
+
12
+
`GraphQLWsLink` requires the [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) library. Install it in your project like so:
13
+
14
+
```shell
15
+
npm install graphql-ws
16
+
```
17
+
18
+
> **Note**: This link works with the newer `graphql-ws` library. If your server uses the older `subscriptions-transport-ws`, you should use the [`WebSocketLink` link from `@apollo/client/link/ws](./apollo-link-ws) instead.
The `GraphQLWsLink` constructor takes a single object. This can either be a `Client` returned from the `graphql-ws``createClient` function, or an options object that will be passed directly to the `createClient` function.
33
+
34
+
If you are passing an options object, the one required option is `url`, which is the URL (typically starting with `ws://` or `wss://`, which are the equivalents of `http://` and `https://` respectively) to your WebSocket server.
35
+
36
+
Full documentation of supported options can be found in [the `graphql-ws` docs for `ClientOptions`](https://github.com/enisdenjo/graphql-ws/blob/master/docs/interfaces/client.ClientOptions.md).
Copy file name to clipboardExpand all lines: docs/source/api/link/apollo-link-ws.md
+6-4Lines changed: 6 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: WebSocket Link
3
-
sidebar_title: WebSocket
4
-
description: Execute subscriptions (or other GraphQL operations) over WebSocket
3
+
sidebar_title: WebSocket (newer protocol)
4
+
description: Execute subscriptions (or other GraphQL operations) over WebSocket with the `subscriptions-transport-ws` library
5
5
api_reference: true
6
6
---
7
7
@@ -15,6 +15,8 @@ The `WebSocketLink` is a [terminating link](./introduction/#the-terminating-link
15
15
npm install subscriptions-transport-ws
16
16
```
17
17
18
+
> **Note**: The `subscriptions-transport-ws` library is not actively maintained. We recommend the use of the `graphql-ws` library instead. These libraries layer different protocols on top of WebSockets, so you do need to ensure you are using the same library in your server and any clients that you support. To use `graphql-ws` from Apollo Client, use the [`GraphQLWsLink` link from `@apollo/client/link/subscriptions](./apollo-link-subscriptions) instead.
19
+
18
20
## Constructor
19
21
20
22
```js
@@ -23,8 +25,8 @@ import { WebSocketLink } from "@apollo/client/link/ws";
Copy file name to clipboardExpand all lines: docs/source/api/react/hoc.mdx
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -471,7 +471,7 @@ data.fetchMore({
471
471
472
472
### `data.subscribeToMore(options)`
473
473
474
-
This function will set up a subscription, triggering updates whenever the server sends a subscription publication. This requires subscriptions to be set up on the server to properly work. Check out the [subscriptions guide](../../data/subscriptions/)and the [subscriptions-transport-ws](https://github.com/apollographql/subscriptions-transport-ws) and [graphql-subscriptions](https://github.com/apollographql/graphql-subscriptions)for more information on getting this set up.
474
+
This function will set up a subscription, triggering updates whenever the server sends a subscription publication. This requires subscriptions to be set up on the server to properly work. Check out the [subscriptions guide](../../data/subscriptions/) for more information on getting this set up.
475
475
476
476
This function returns an `unsubscribe` function handler which can be used to unsubscribe later.
Copy file name to clipboardExpand all lines: docs/source/data/subscriptions.mdx
+58-31Lines changed: 58 additions & 31 deletions
Original file line number
Diff line number
Diff line change
@@ -22,6 +22,14 @@ You _should_ use subscriptions for the following:
22
22
23
23
***Low-latency, real-time updates**. For example, a chat application's client wants to receive new messages as soon as they're available.
24
24
25
+
## Choice of subscription protocol
26
+
27
+
The GraphQL spec does not define a specific way to send subscription requests. The first popular JavaScript library to implement subscriptions over WebSocket is called `subscriptions-transport-ws`. This library is no longer actively maintained; its successor is a library called `graphql-ws`. The two packages _do not use the same protocol_, so you need to make sure that your server and clients all use the same library.
28
+
29
+
Apollo Client supports both `graphql-ws` and `subscriptions-transport-ws`. We recommend you use the newer library `graphql-ws` and this page shows how to use it. If you need to use `subscriptions-transport-ws` because your server still uses that protocol, the differences are described [at the bottom of this page](#the-older-subscriptions-transport-ws-library).
30
+
31
+
> **Note**: When looking at the source code of an implementation to determine which protocol it supports, you will find that the libraries uses different strings as the "WebSocket subprotocol". Confusingly, `subscriptions-transport-ws` uses the `graphql-ws` subprotocol and `graphql-ws` uses the `graphql-transport-ws` subprotocol! In these docs, when we say "`graphql-ws`" we are referring to the _library_`graphql-ws`, not the subprotocol `graphql-ws`, which is the other project.
32
+
25
33
## Defining a subscription
26
34
27
35
You define a subscription on both the server side and the client side, just like you do for queries and mutations.
@@ -70,57 +78,51 @@ Whenever your GraphQL server _does_ push data to a subscribing client, that data
70
78
71
79
## Setting up the transport
72
80
73
-
Because subscriptions usually maintain a persistent connection, they shouldn't use the default HTTP transport that Apollo Client uses for queries and mutations. Instead, Apollo Client subscriptions most commonly communicate over WebSocket, via the community-maintained [`subscriptions-transport-ws`](https://github.com/apollographql/subscriptions-transport-ws)library.
81
+
Because subscriptions usually maintain a persistent connection, they shouldn't use the default HTTP transport that Apollo Client uses for queries and mutations. Instead, Apollo Client subscriptions most commonly communicate over WebSocket, via the [`graphql-ws`](https://www.npmjs.com/package/graphql-ws) library. (As mentioned [above](#choice-of-subscription-protocol), some servers use an older library called `subscriptions-transport-ws`; see [below](#the-older-subscriptions-transport-ws-library) for the changes necessary to use that library with Apollo Client.)
74
82
75
83
### 1. Install required libraries
76
84
77
85
[Apollo Link](../api/link/introduction/) is a library that helps you customize Apollo Client's network communication. You can use it to define a **link chain** that modifies your operations and routes them to the appropriate destination.
78
86
79
-
To execute subscriptions over WebSocket, you can add a `WebSocketLink` to your link chain. This link requires the `subscriptions-transport-ws` library. Install it like so:
87
+
To execute subscriptions over WebSocket, you can add a `GraphQLWsLink` to your link chain. This link requires the `graphql-ws` library. Install it like so:
Replace the value of the `uri` option with your GraphQL server's subscription-specific WebSocket endpoint. If you're using Apollo Server, see [Setting a subscription endpoint](https://www.apollographql.com/docs/apollo-server/data/subscriptions/#setting-a-subscription-endpoint).
105
+
Replace the value of the `url` option with your GraphQL server's subscription-specific WebSocket endpoint. If you're using Apollo Server, see [Setting a subscription endpoint](https://www.apollographql.com/docs/apollo-server/data/subscriptions/#setting-a-subscription-endpoint).
101
106
102
107
### 3. Split communication by operation (recommended)
103
108
104
-
Although Apollo Client _can_ use your `WebSocketLink` to execute all operation types, in most cases it should continue using HTTP for queries and mutations. This is because queries and mutations don't require a stateful or long-lasting connection, making HTTP more efficient and scalable if a WebSocket connection isn't already present.
109
+
Although Apollo Client _can_ use your `GraphQLWsLink` to execute all operation types, in most cases it should continue using HTTP for queries and mutations. This is because queries and mutations don't require a stateful or long-lasting connection, making HTTP more efficient and scalable if a WebSocket connection isn't already present.
105
110
106
111
To support this, the `@apollo/client` library provides a `split` function that lets you use one of two different `Link`s, according to the result of a boolean check.
107
112
108
-
The following example expands on the previous one by initializing both a `WebSocketLink`_and_ an `HttpLink`. It then uses the `split` function to combine those two `Link`s into a _single_`Link` that uses one or the other according to the type of operation being executed.
113
+
The following example expands on the previous one by initializing both a `GraphQLWsLink`_and_ an `HttpLink`. It then uses the `split` function to combine those two `Link`s into a _single_`Link` that uses one or the other according to the type of operation being executed.
@@ -162,24 +164,20 @@ const client = new ApolloClient({
162
164
163
165
### 5. Authenticate over WebSocket (optional)
164
166
165
-
It is often necessary to authenticate a client before allowing it to receive subscription results. To do this, you can provide a `connectionParams` option to the `WebSocketLink` constructor, like so:
167
+
It is often necessary to authenticate a client before allowing it to receive subscription results. To do this, you can provide a `connectionParams` option to the `GraphQLWsLink` constructor, like so:
166
168
167
169
```js{7-9}
168
-
import { WebSocketLink } from '@apollo/client/link/ws';
170
+
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
169
171
170
-
const wsLink = new WebSocketLink({
171
-
uri: 'ws://localhost:4000/subscriptions',
172
-
options: {
173
-
reconnect: true,
174
-
connectionParams: {
175
-
authToken: user.authToken,
176
-
},
172
+
const wsLink = new GraphQLWsLink({
173
+
url: 'ws://localhost:4000/subscriptions',
174
+
connectionParams: {
175
+
authToken: user.authToken,
177
176
},
178
177
});
179
178
```
180
179
181
-
Your `WebSocketLink` passes the `connectionParams` object to your server whenever it connects. If your server has a [SubscriptionsServer](https://www.apollographql.com/docs/graphql-subscriptions/authentication) object that's listening for WebSocket connections, it receives the `connectionParams` object and can use it to perform authentication, along with any other connection-related tasks.
182
-
180
+
Your `GraphQLWsLink` passes the `connectionParams` object to your server whenever it connects. Your server receives the `connectionParams` object and can use it to perform authentication, along with any other connection-related tasks.
183
181
184
182
## Executing a subscription
185
183
@@ -312,3 +310,32 @@ The `useSubscription` Hook accepts the following options:
312
310
After being called, the `useSubscription` Hook returns a result object with the following properties:
313
311
314
312
<SubscriptionResult />
313
+
314
+
## The older `subscriptions-transport-ws` library
315
+
316
+
If your server uses `subscriptions-transport-ws` instead of the newer `graphql-ws` library, you need to make a few changes to how you set up your link.
317
+
318
+
Instead of `npm install graphql-ws`, you `npm install subscriptions-transport-ws`
319
+
320
+
Instead of `import { GraphQLWsLink } from '@apollo/client/link/subscriptions'`, you `import { WebSocketLink } from '@apollo/client/link/ws`.
321
+
322
+
The options passed to the link constructor are slightly different. The subscriptions URL is specified in an `uri` option instead of an `url` option. The `connectionParams` option is nested under an options object called `options` instead of being at the top level.
323
+
324
+
Once you've created your `wsLink`, everything else in this document still applies: `useSubscription`, `subscribeToMore`, and split links work exactly the same way for both implementations.
325
+
326
+
The following is what typical `WebSocketLink` initialization looks like:
0 commit comments