В настоящее время у меня есть API-интерфейс graphql, который обрабатывает HTTP-запросы, я перешел на apollo-client и теперь хочу добавить подписки. Проблема в том, что я не могу понять, как объединить мою ссылку HTTP (с промежуточным программным обеспечением для аутентификации JWT).
У меня нет ошибок в коде, но проблема заключается в том, как я используюссылка split
метод. Почему? потому что когда я удаляю его и просто использую authLink.concat(httpLink)
, все работает гладко (за исключением того, что в этом случае я не проверяю, является ли соединение WS или HTTP ...).
Вот мой код:
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");