2

I currently have a graphql api that handles HTTP requests, I've migrated to apollo-client and now I want to add subscriptions. The problem is, that I can't figure out how to combine my HTTP link (that has a JWT auth middleware).

I have no code errors to share, BUT, the issue is in the way i use the link split method. why? because when I remove it and just use authLink.concat(httpLink) everything works smoothly (except for that in this case I don't check if the connection is WS or HTTP...).

Here's my code:

import Vue from "vue";
import App from "./App.vue";
import router from "./router";

// import ApolloClient from "apollo-boost"; // migrated to apollo-client
import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';

// subscriptions imports
import { split } from 'apollo-link'
import { WebSocketLink } from 'apollo-link-ws';
import { getMainDefinition } from 'apollo-utilities';
import VueApollo from "vue-apollo";

// links composition
const httpLink = createHttpLink({
  uri: 'http://localhost:4000/graphql',
});
const wsLink = new WebSocketLink({
  uri: `ws://localhost:5000`,
  options: {
    reconnect: true
  }
});

// this is the sketchy section
const link = split(
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query)
    return kind === 'OperationDefinition' && operation === 'subscription'
  },
  wsLink,
  httpLink
)

// JWT middleware
const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token');
  return {
    headers: {
      ...headers,
      authorization: token ? token : ''
    }
  }
});

const wsPlusHttpWithJWT = authLink.concat(link)

export const apolloClient = new ApolloClient({
  // link: authLink.concat(httpLink), // this worked
  link: wsPlusHttpWithJWT,
  cache: new InMemoryCache()
});

Vue.use(VueApollo);

const apolloProvider = new VueApollo({ defaultClient: apolloClient });

Vue.config.productionTip = false;

new Vue({
  apolloProvider,
  router,
  render: h => h(App),
}).$mount("#app");
toti
  • 325
  • 4
  • 12

0 Answers0