阿波罗链接状态设置?

时间:2018-05-19 05:37:06

标签: apollo

我试图按照文档设置Apollo链接状态:https://github.com/apollographql/apollo-link-state

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { HttpLink, InMemoryCache, ApolloClient } from 'apollo-client-preset';
    import { WebSocketLink } from 'apollo-link-ws';
    import { ApolloLink, split } from 'apollo-link';
    import { getMainDefinition } from 'apollo-utilities';
    import { AUTH_TOKEN } from './constant';
    import RootContainer from './components/RootContainer';
    import { ApolloProvider } from 'react-apollo';

    const httpLink = new HttpLink({ uri: 'http://localhost:4000' });

    const middlewareLink = new ApolloLink((operation, forward) => {
ation token from local storage if it exists
      const tokenValue = localStorage.getItem(AUTH_TOKEN);
      operation.setContext({
        headers: {
          Authorization: tokenValue ? `Bearer ${tokenValue}` : '',
        },
      });
      return forward(operation);
    });

    const httpLinkAuth = middlewareLink.concat(httpLink);

    const wsLink = new WebSocketLink({
      uri: `ws://localhost:4000`,
      options: {
        reconnect: true,
        connectionParams: {
          Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN)}`,
        },
      },
    });

    const link = split(
      ({ query }) => {
        const { kind, operation } = getMainDefinition(query);
        return kind === 'OperationDefinition' && operation === 'subscription';
      },
      wsLink,
      httpLinkAuth,
    );

    const client = new ApolloClient({
      clientState: {
        defaults: {
          isConnected: true,
        },
        resolvers: {
          Mutation: {
            updateNetworkStatus: (_, { isConnected }, { cache }) => {
              cache.writeData({ data: { isConnected } });
              return null;
            },
          },
        },
      },

      link: ApolloLink.from([link]),

      cache: new InMemoryCache(),

      connectToDevTools: true,
    });

    const token = localStorage.getItem(AUTH_TOKEN);

    ReactDOM.render(
      <ApolloProvider client={client}>
        <RootContainer token={token} />
      </ApolloProvider>,
      document.getElementById('root'),
    );

当我尝试查询时:

{
  networkStatus @client {
    isConnected
  }
}

我收到此错误

    {
  "errors": [
    {
      "message": "Response not successful: Received status code 400",
      "locations": [
        "Error: Response not successful: Received status code 400\n    at throwServerError (http://localhost:3000/static/js/bundle.js:5296:17)\n    at http://localhost:3000/static/js/bundle.js:5321:13"
      ]
    }
  ]
}

更新的代码:我不再收到错误,但返回的查询始终是一个空对象。

import React from 'react';
import ReactDOM from 'react-dom';
import { HttpLink, InMemoryCache, ApolloClient } from 'apollo-client-preset';
import { WebSocketLink } from 'apollo-link-ws';
import { ApolloLink, split } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
import { AUTH_TOKEN } from './constant';
import RootContainer from './components/RootContainer';
import { ApolloProvider } from 'react-apollo';
import { withClientState } from 'apollo-link-state';
import { gql } from 'apollo-boost';

const httpLink = new HttpLink({ uri: 'http://localhost:4000' });

const middlewareLink = new ApolloLink((operation, forward) => {
  // get the authentication token from local storage if it exists
  const tokenValue = localStorage.getItem(AUTH_TOKEN);
  // return the headers to the context so httpLink can read them
  operation.setContext({
    headers: {
      Authorization: tokenValue ? `Bearer ${tokenValue}` : '',
    },
  });
  return forward(operation);
});

// authenticated httplink
const httpLinkAuth = middlewareLink.concat(httpLink);

const wsLink = new WebSocketLink({
  uri: `ws://localhost:4000`,
  options: {
    reconnect: true,
    connectionParams: {
      Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN)}`,
    },
  },
});

const link = split(
  // split based on operation type
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query);
    return kind === 'OperationDefinition' && operation === 'subscription';
  },
  wsLink,
  httpLinkAuth,
);

const cache = new InMemoryCache();

const stateLink = withClientState({
  cache,
  resolvers: {
    Query: {
      networkStatus: (_, args, { cache }) => {
        return cache.readQuery({
          query: gql`
            query {
              networkStatus @client {
                isConnected
              }
            }
          `,
        });
      },
    },
    Mutation: {
      updateNetworkStatus: (_, { isConnected }, { cache }) => {
        const data = {
          networkStatus: {
            __typename: 'NetworkStatus',
            isConnected,
          },
        };
        cache.writeData({ data });
        return null;
      },
    },
  },
  defaults: {
    networkStatus: {
      __typename: 'NetworkStatus',
      isConnected: true,
    },
  },
});

// apollo client setup
const client = new ApolloClient({
  link: ApolloLink.from([stateLink, link]),
  cache,
  connectToDevTools: true,
});

const token = localStorage.getItem(AUTH_TOKEN);

ReactDOM.render(
  <ApolloProvider client={client}>
    <RootContainer token={token} />
  </ApolloProvider>,
  document.getElementById('root'),
);

如果我删除默认值,则无法识别查询。所以我认为无论是写作还是从商店阅读都不正确。

1 个答案:

答案 0 :(得分:1)

您还没有真正配置状态链接。来自docs的示例配置:

import { withClientState } from 'apollo-link-state';

// This is the same cache you pass into new ApolloClient
const cache = new InMemoryCache(...);

const stateLink = withClientState({
  cache,
  resolvers: {
    Mutation: {
      updateNetworkStatus: (_, { isConnected }, { cache }) => {
        const data = {
          networkStatus: {
            __typename: 'NetworkStatus',
            isConnected
          },
        };
        cache.writeData({ data });
        return null
      },
    },
  }
});

然后,您必须将其包含在客户端配置中:

link: ApolloLink.from([stateLink, link])