Hi,
Since addGraphQLSubscriptions is removed from new version. How to achieve the hybrid subscriptions with ws now? Or can you please update the README, because now it's still showing using addGraphQLSubscriptions function to do it.
Hey @grissom1
This should be done using 'apollo-link-ws' + 'apollo-link-http'
Using 'apollo-link-split' for miltiplexing requests.
More info can be found here
Couldnt find a code example though
This should be updated at soon at possible, does anyone have a working example? thank you.
I have not tested this code, but I'm guessing that anything closer to that could work @grissom1 @lednhatkhanh @DxCx :
import { getOperationAST } from 'graphql';
const link = ApolloLink.split(
operation => {
const operationAST = getOperationAST(operation.query, operation.operationName);
return !!operationAST && operationAST.operation === 'subscription';
},
new WebSocketLink..., // complete this
new HttpLink..., // complete this
);
// use this link...
yep @mistic exactly..
need to check documentation that left is left and right is right but yeah that's how it goes..
This is definitely of concern, since the tutorial on howtographql still references the older implementation. The docs should certainly be updated since new users may be turned off by this frustration. I'm going to revert to an older version for the time being until a new strategy is more easily obtained.
Still a noob to graphql, or I'd try to tough this out
Hey @mistic thank you for your initial thoughts on this topic. I'm currently trying to implement a Network Interface for Relay Modern and wanted to make use of your solution with Apollo-Link. The Apollo-Link documentation explicitly states that this is one of its use cases but does not provide any documentation or examples. Here is what I've come up with so far (the initial _network_ is commented out):
import { Environment, Network, RecordSource, Store } from 'relay-runtime';
import { SubscriptionClient } from 'subscriptions-transport-ws';
import { getOperationAST } from 'graphql';
import { ApolloLink, WebSocketLink, HttpLink } from 'apollo-link';
// Define a function that fetches the results of an operation
// and returns its results as a Promise:
function fetchQuery(operation: { text: string }, variables: Object) {
// eslint-disable-next-line
return fetch('/graphql', {
method: 'POST',
headers: {
// Add authentication and other headers here
'content-type': 'application/json',
},
body: JSON.stringify({
query: operation.text, // GraphQL text from input
variables,
}),
}).then(response => response.json());
}
// Create WebSocket client
const wsClient = new SubscriptionClient(`ws://localhost:3000/subscriptions`, {
reconnect: true,
connectionParams: {
// Pass any arguments you want for initialization
},
});
// const network = Network.create(fetchQuery);
const network = ApolloLink.split(
operation => {
const operationAST = getOperationAST(
operation.query,
operation.operationName,
);
return !!operationAST && operationAST.operation === 'subscription';
},
new WebSocketLink(wsClient),
new HttpLink({ fetch: fetchQuery }),
);
const environment = new Environment({
network,
store: new Store(new RecordSource()),
});
Now, this throws the following error:
Failed to construct 'WebSocket': The URL 'undefined' is invalid.
Now I'm a bit lost since I am fairly new to all of this and documentation is a bit sparse. Any idea what's wrong here? Why is URL undefined? Thanks!
Hey guys,
Just ran into this myself and got it working using the new-fangled apollo-link library announced a few months back, using the ApolloLink.from function to combine an HttpLink with a WebSocketLink.
I actually did not even refer to SubscriptionClient directly, as it appears that the WebSocketLink already does. Now, the next thing I'm planning on testing is if the ApolloClient will still have the subscribe convenience function given this.
The code below should at least get you connected to WebSockets using apollo-link. If somebody beats me to the punch, let me know if the code below enhances the Apollo Client with a subscribe function!
import React from 'react';
import ReactDOM from 'react-dom';
import './common/assets/styles/index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
// Apollo
import { ApolloClient, ApolloProvider } from 'react-apollo';
import { ApolloLink, HttpLink, WebSocketLink } from 'apollo-link';
// Redux
import { Provider } from 'react-redux';
import { initializeCurrentLocation } from 'redux-little-router';
import configureStore from './common/store/configureStore';
const store = configureStore();
// redux-little-router boilerplate
const initialLocation = store.getState().router;
if (initialLocation) {
store.dispatch(initializeCurrentLocation(initialLocation));
}
// GraphQL via Apollo
const httpLink = new HttpLink({ uri: process.env.REACT_APP_API_ROOT });
const wsLink = new WebSocketLink({ uri: process.env.REACT_APP_WS_ROOT });
const link = ApolloLink.from([httpLink, wsLink]);
const client = new ApolloClient({ networkInterface: link });
ReactDOM.render(
<Provider store={store}>
<ApolloProvider client={client}>
<App />
</ApolloProvider>
</Provider>,
document.getElementById('root')
);
registerServiceWorker();
FYI, no bueno y'all. Don't see a subscribe function underneath my ApolloClient. I'll do some digging in the source and see if I can get any clues as to how to stitch the two sides together.
Note that it also could be that I don't quite have my server up-to-snuff yet with WebSockets, so I'm wondering if subscribe just is not added if a WebSocket connection fails.

@ericnograles if you are using apollo client 2 then watchQuery should return an Observable and you should use that for subscriptions as well.
Thanks @DxCx I'll check it out!
Looks like watchQuery is also a function for apollo-client 1.8.1, which is what react-apollo is bound to. Will give it a try once I find docs around it 馃槃

I can't get subscriptions to work with [email protected] ...
const http = new HttpLink({ uri: 'http://localhost:3000/graphql' });
const socket = new WebSocketLink({ uri: 'ws://localhost:3000/subscriptions' });
const link = ApolloLink.from([http, socket]);
const cache = new Cache(window.__APOLLO_STATE);
const client = new ApolloClient({
link,
cache
});
I am getting this warning Error: You are calling concat on a terminating link, which will have no effect
@mattiasewers see @mistic example above on how to construct link..
your link is incorrect.
@ericnograles you want apollo-client@2 with [email protected]
i dont think [email protected] supports link interface..
I don't mean to add to the noise, but this seems to be a struggle point for a lot of people right now. I made this write-up with the hopes of making the transition to Apollo 2.0 clearer. I haven't been involved in the development of Apollo, but I'm really excited about where it's going and my company is using it as a core piece of its software. It also fits nicely with Meteor, which I have used for several projects for several years now and continue to use. My company right now depends on it heavily. I don't write much, but I'm a silent supporter. I've also made an example app showing how to use Apollo 2.0 in Meteor, if that proves useful to someone.
same issue..
Unable to use Subscription with subscriptions-transport-ws & beta Apollo Client 2.0...
still waiting for release update...
"apollo-client": "^2.0.0-rc.3" and subscriptions-transport-ws 0.9.1 still error
Failed to construct 'WebSocket': The URL 'undefined' is invalid.
Error: Failed to construct 'WebSocket': The URL 'undefined' is invalid.
at SubscriptionClient.module.exports.SubscriptionClient.connect (http://localhost:3003/_next/1508001645971/page/sub:32314:23)
at new SubscriptionClient (http://localhost:3003/_next/1508001645971/page/sub:31945:18)
at new WebSocketLink (http://localhost:3003/_next/1508001645971/page/sub:31877:40)
at createLink (http://localhost:3003/_next/1508001645971/page/sub:26766:16)
at create (http://localhost:3003/_next/1508001645971/page/sub:26783:11)
at initApollo (http://localhost:3003/_next/1508001645971/page/sub:26807:20)
function createLink() {
const links = [];
links.push(new HttpLink({ uri: "/graphql" }));
if (process.browser) {
const subUrl = "ws://localhost:3003/subscriptions";
const subClient = new SubscriptionClient(
subUrl,
{
reconnect: true
},
err => {
console.log(err);
}
);
links.push(new WebSocketLink(subClient));
}
return ApolloLink.from(links);
}
update apollo-link-ws to version 0.6.0 will be fine
Most helpful comment
I don't mean to add to the noise, but this seems to be a struggle point for a lot of people right now. I made this write-up with the hopes of making the transition to Apollo 2.0 clearer. I haven't been involved in the development of Apollo, but I'm really excited about where it's going and my company is using it as a core piece of its software. It also fits nicely with Meteor, which I have used for several projects for several years now and continue to use. My company right now depends on it heavily. I don't write much, but I'm a silent supporter. I've also made an example app showing how to use Apollo 2.0 in Meteor, if that proves useful to someone.