在nextJS上为订阅配置apollo客户端时出现问题

时间:2019-09-26 02:01:34

标签: apollo next.js

因此,Apollo客户端可用于进行GraphQL查询和变异调用,但是当我配置websocket Link时,在浏览器上出现错误:Error: ws does not work in the browser. Browser clients must use the native WebSocket object

我确实尝试了本文,但没有成功-> https://github.com/apollographql/subscriptions-transport-ws/issues/333

    const isBrowser = typeof window !== 'undefined';

    const authLink = setContext((_, { headers }) => {
        const token = getToken();
        console.log('Token', token);
        // return the headers to the context so httpLink can read them
        return {
            headers: {
                ...headers,
                authorization: token ? `Bearer ${token}` : "",
            }
        }
    });

    const wsLink =  isBrowser ? new WebSocketLink({
        uri: 'ws://127.0.0.1:8080/v1/graphql',
        options: {
            lazy: true,
            reconnect: true,
            connectionParams: () => {
                const token = getToken();
                return {headers: {Authorization: `Bearer ${token}`}}
            }
        },
        webSocketImpl: ws
    }): null;

    const terminatingLink = isBrowser ? split(
        ({ query }) => {
            const { kind, operation } = getMainDefinition(query);
            return kind === "OperationDefinition" && operation === "subscription";
        },
        wsLink,
        authLink.concat(httpLink)
    ): authLink.concat(httpLink);
    const link = ApolloLink.from([reportErrors, terminatingLink]);

    return new ApolloClient({
        connectToDevTools: isBrowser,
        ssrMode: !isBrowser, // Disables forceFetch on the server (so queries are only run once)
        link: link,
        cache: new InMemoryCache().restore(initialState || {})
    });
}

2 个答案:

答案 0 :(得分:1)

我遇到了相同的问题,并提出了package来解决它。它支持启用了SSR的查询/变异/订阅。

答案 1 :(得分:0)

对我来说很好。对于以前的阿波罗版本,您可以检查@xiao's package

import nextWithApollo from "next-with-apollo";
import {
  ApolloProvider,
  ApolloClient,
  ApolloLink,
  HttpLink,
  split,
} from "@apollo/client";
import { getDataFromTree } from "@apollo/client/react/ssr";
import { getMainDefinition } from "@apollo/client/utilities";
import { InMemoryCache } from "@apollo/client/cache";
import { WebSocketLink } from "@apollo/link-ws";
import fetch from "isomorphic-unfetch";

export const withApollo = (
  component: Parameters<ReturnType<typeof nextWithApollo>>[0]
): ReturnType<ReturnType<typeof nextWithApollo>> => {
  const wsUrl = `ws://localhost:8000/graphql`;
  const httpUrl = `http://localhost:8000/graphql`;
  if (!httpUrl) {
    throw new Error(
      "either url or httpUrl must be provided to make an apollo connection"
    );
  }

  const ssrMode = !process.browser;

  const httpLink: ApolloLink = new HttpLink({
    uri: httpUrl,
    credentials: "same-origin",
    fetch,
  });
  let link = httpLink;
  if (!ssrMode && wsUrl) {
    const wsLink = new WebSocketLink({
      uri: wsUrl,
      options: {
        reconnect: true,
      },
      webSocketImpl: WebSocket,
    });
    link = split(
      ({ query }) => {
        const def = getMainDefinition(query);
        return (
          def.kind === "OperationDefinition" && def.operation === "subscription"
        );
      },
      wsLink,
      httpLink
    );
  }

  return nextWithApollo(
    ({ initialState }) => {
      return new ApolloClient({
        link,
        ssrMode,
        connectToDevTools: !ssrMode,
        cache: new InMemoryCache().restore((initialState as any) || {}),
      });
    },
    {
      render: ({ Page, props }) => (
        <ApolloProvider client={props.apollo}>
          <Page {...props} />
        </ApolloProvider>
      ),
    }
  )(component, { getDataFromTree });
};