Apollo Urgently Needs Better Docs for Subscriptions

I don’t urgently need this – I already put in 50+ hours to solve it. :slightly_frowning_face: But why did I have to?

Apollo has the fantastic lift-off series which is so well done. It provides awesome docs on Apollo Server and Client setup. But it doesn’t talk about how to setup subscriptions with context.

Why isn’t there documentation for this?

How many new users are being blocked from using Apollo due to this glaring absence of documentation?

</soapbox>

Hi @vikr00001 :wave: so sorry you found the documentation lacking here. Did you happen to notice this Operation context area of Apollo Server’s Subscriptions docs?

I’m wondering what we can do in order to make that info more present - are you suggesting that we add it to the Lift-off series as well? Thanks for sticking with it, eager to hear how we could have made it better in hindsight :pray:

I did see that, and it was helpful. But without a matching Apollo Client setup, it didn’t work.

I’m wondering what we can do in order to make that info more present - are you suggesting that we add it to the Lift-off series as well?

Yes, 100%

Hello,
I can understand your issue after investing over 50 hours into this issue. It’s disappointing that Apollo’s Lift-off series 1, despite its thoroughness, lacks documentation on setting up subscriptions with context. This gap in documentation can indeed be a barrier for new users. It might be helpful to provide feedback directly to Apollo’s support or community forum to highlight this issue and encourage the addition of comprehensive documentation for subscription setup with context.

1 Like

Once I pushed to production, I found my production server can only handle connections on port 3000. I had to change my Apollo Server setup to listen on port 3000, and now my Apollo Client setup doesn’t connect to my Apollo Server setup for subscriptions (queries/mutations work fine).

@ JeffAuriemma or others here, could you please post an Apollo Client setup that matches the Apollo Server setup shown in the docs on this page?

If it may be helpful, here’s my current ApolloClient setup:

import {ApolloClient, split, HttpLink, InMemoryCache, ApolloLink, ApolloProvider, createHttpLink} from "@apollo/client";
import {GraphQLWsLink} from "@apollo/client/link/subscriptions";
import {setContext} from "@apollo/client/link/context";
import {getMainDefinition} from "@apollo/client/utilities";
import {createClient} from "graphql-ws";
import {graphQLQueryEndpoint, graphQLSubscriptionEndpoint, GRAPHQL_PORT} from "../both";

// note:
// graphQLQueryEndpoint ==  'http://localhost:3000/graphql'
// graphQLSubscriptionEndpoint ==  'ws://localhost:3000/graphql'

const wsLink = new GraphQLWsLink(
        createClient({
            url: graphQLSubscriptionEndpoint,
            connectionParams: () => {
                return {
                    authorization: localStorage.getItem("Meteor.loginToken") || "",
                };
            },
            on: {
                error: props => {
                    console.log("wsLink error in apollo_client setup", props);
                },
            },
        }),
    );

const httpLink = createHttpLink({
    uri: graphQLQueryEndpoint,
    fetchOptions: {
        rejectUnauthorized: false,
    },
});


// Middleware to add custom headers
const customHeadersMiddleware = new ApolloLink((operation, forward) => {
    // Define your custom headers
    const customHeaders = {
        "token": localStorage.getItem("Meteor.loginToken")
    };

    // Use operation.setContext to add the custom headers to the request
    operation.setContext(({ headers }) => ({
        headers: {
            ...headers,
            ...customHeaders,
        },
    }));

    return forward(operation);
});

const splitLink = split(
    ({ query }) => {
        const definition = getMainDefinition(query);
        return (
            definition.kind === 'OperationDefinition' &&
            definition.operation === 'subscription'
        );
    },
    customHeadersMiddleware.concat(wsLink),
    customHeadersMiddleware.concat(httpLink)
)

const apolloClient = new ApolloClient({
    link: splitLink,
    cache: new InMemoryCache({}),
});


export {apolloClient};