Apollo subscriptions in meteor apollo package


#1

Can anyone provide an example how to use apollo subscriptions with meteor apollo package if it even possible?


#2

Apollo subscriptions are working. Here is working Apollo subscription code which I posted to StackOverflow in response to a question:


#3

Thanks @vikr00001 ,

I get a TypeError: _this.networkInterface.subscribe is not a function error, but I think I’m close to resolve this. Should I do something like new PubSub() on the server as here?

Right now my apolloServer:

const schema = makeExecutableSchema({
  typeDefs,
  resolvers,
});

createApolloServer({
    schema,
});

and on the client

const apolloClient = new ApolloClient(meteorClientConfig());

Is it enough to setup schema and resolvers to get subscriptions work?


#4

Here’s my code for setting up the server, in server/main.js:

//SET UP APOLLO QUERY AND MUTATIONS
import express from 'express';
import Schema from '/imports/api/schema';
import Mocks from '/imports/api/mocks';
import Resolvers from '/imports/api/resolvers';
import Connectors from '/imports/api/db-connectors';
import { apolloExpress, graphiqlExpress } from 'apollo-server';
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
import  cors  from 'cors';
import bodyParser from 'body-parser';
import { createServer } from 'http';
import { SubscriptionServer } from 'subscriptions-transport-ws';


const GRAPHQL_PORT = 3010;
const SUBSCRIPTION_PORT = 8080;
const graphQLServer = express();

//TAKE CARE OF CORS
//http://stackoverflow.com/a/33483759/364966
var whitelist = [
    'http://localhost:3000',
];
var corsOptions = {
    origin: function(origin, callback){
        var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
        callback(null, originIsWhitelisted);
    },
    credentials: true
};
graphQLServer.use(cors(corsOptions));
//END OF CODE TO TAKE CARE OF CORS

// `context` must be an object and can't be undefined when using connectors
graphQLServer.use('/graphql', bodyParser.json(), apolloExpress({
    schema: Schema,
    context: {}, //at least(!) an empty object
}));

graphQLServer.use('/graphiql', graphiqlExpress({
    endpointURL: '/graphql',
}));

graphQLServer.listen(GRAPHQL_PORT, () => console.log(
    `GraphQL Server is now running on http://localhost:${GRAPHQL_PORT}/graphql`
));
//END OF SET UP APOLLO QUERIES AND MUTATIONS

//SET UP APOLLO PUBSUB
// WebSocket server for subscriptions
const ApolloPubSubServer = createServer((request, response) => {
    response.writeHead(404);
    response.end();
});

ApolloPubSubServer.listen(SUBSCRIPTION_PORT, () => console.log( // eslint-disable-line no-console
    `Websocket Server is now running on http://localhost:${SUBSCRIPTION_PORT}`
));

// eslint-disable-next-line
new SubscriptionServer(
    {
        subscriptionManager,

        // the obSubscribe function is called for every new subscription
        // and we use it to set the GraphQL context for this subscription
        onSubscribe: (msg, params) => {

            return Object.assign({}, params, {
                context: {},
            });
        },
    },
    ApolloPubSubServer
);
//END OF SET UP APOLLO PUBSUB

And on the client:

import ApolloClient, { createBatchingNetworkInterface, addTypename } from 'apollo-client';


const graphQLClient = new Client('ws://localhost:8080', { reconnect: true });

const networkInterface = createBatchingNetworkInterface({
    uri: 'http://localhost:3010/graphql',
    opts: {
        credentials: 'same-origin',
    },
    transportBatching: true,
    batchInterval: 10
});


const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
    networkInterface,
    graphQLClient,
);

const ApolloClientWithSubscribeEnabled = new ApolloClient({
    networkInterface: networkInterfaceWithSubscriptions,
    queryTransformer: addTypename,
    dataIdFromObject: (result) => {
        if (result.id && result.__typename) { // eslint-disable-line no-underscore-dangle
            return result.__typename + result.id; // eslint-disable-line no-underscore-dangle
        }
        return null;
    },
    shouldBatch: true,
    initialState: window.__APOLLO_STATE__, // eslint-disable-line no-underscore-dangle
    ssrForceFetchDelay: 100,
});

Make sure you are using the latest versions of all the Apollo-related npm packages.


#5

Do you have github for example for these, such as todo app?


#6

This is now available out-of-the-box in ddp-apollo:

Sadly, the apollo package still only provides an HTTP server, no subscriptions.