【问题标题】:Update ApolloClient headers after it was initialised初始化后更新 ApolloClient 标头
【发布时间】:2019-09-18 01:11:41
【问题描述】:

我的应用程序包含<Apollo /> 组件,该组件本质上是初始化客户端。

const client = new ApolloClient({
  link: new HttpLink({
    // ...
  }),
  cache: new InMemoryCache({
    // ..
  }),
});

进一步,用户可以进行某些操作,需要我为 apollo 客户端设置一些以前没有的新标头。我最初想为此使用反应上下文来传递设置的新标头并在<Apollo /> 中使用它们,但不确定这是否是正确的方法。

查看文档后,似乎只有在初始化时才能设置apollo headers?

【问题讨论】:

    标签: reactjs graphql apollo react-apollo


    【解决方案1】:

    您通常希望使用apollo-link-context,而不是将标头直接传递给您的 Apollo 客户端实例。您可以将实际的标头值存储在内存、LocalStorage 或对您的应用程序有意义的任何内容中。然后在发送之前使用链接将它们注入到每个请求中:

    const headerLink = setContext((request, previousContext) => ({
      headers: {
        // Make sure you include any existing headers!
        ...previousContext.headers,
        authorization: localStorage.getItem('authHeader')
      },
    }));
    
    const client = new ApolloClient({
      link: headerLink.concat(httpLink),
      cache: new InMemoryCache()
    });
    

    setContext 可以是异步的。您传递给它的函数应该返回一个包含您想要更改的任何上下文字段的对象,或者一个将解析为一个的 Promise:

    const headerLink = setContext(async (request, previousContext) => {
      const authorization = await someAsyncCall()
      return {
        headers: {
          ...previousContext.headers,
          authorization,
        },
      }
    });
    

    您可以查看the docs 了解更多示例。

    【讨论】:

    • 但事后如何更新呢?例如,初始 GraphQL 登录请求没有 Authorization 标头。登录后,如何更新 ApolloClient 实例?您是否将其替换为全新的 ApolloClient?
    【解决方案2】:

    丹尼尔·里尔登是对的。但是,在 Apollo 3 中,我发现文档中的一些小改动还没有很好地系统化。所以也许它也会有所帮助。

    import React from 'react';
    import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client';
    import { setContext } from '@apollo/client/link/context';
    
    function App() {
    
      const link = new HttpLink({ uri: process.env.REACT_APP_GRAPHQL_URI });
    
      const setAuthorizationLink = setContext((request, previousContext) => ({
        headers: {
          ...previousContext.headers,
          authorization: `Bearer ${ localStorage.getItem('auth_token') }`
        }
      }));
    
      const client = new ApolloClient({
        link: setAuthorizationLink.concat(link),
        cache: new InMemoryCache()
      });
    
      return (
        <ApolloProvider client={client}>
          ...
        </ApolloProvider>
      );
    }
    
    export default App;
    

    Migrating to Apollo Client 3.0 (docs)

    【讨论】:

    • 登录的例子呢?第一个 GraphQL 请求,没有 Authorization 标头。响应返回后如何设置?你如何在你的应用程序中更新标题,然后,在链中?
    猜你喜欢
    • 2020-08-06
    • 2023-03-28
    • 2019-10-07
    • 2012-07-12
    • 2017-02-15
    • 2014-03-21
    • 1970-01-01
    • 2019-10-16
    • 2015-04-08
    相关资源
    最近更新 更多