初始化后更新 ApolloClient headers
Update ApolloClient headers after it was initialised
我的应用程序包含 <Apollo />
组件,该组件实质上是初始化客户端。
const client = new ApolloClient({
link: new HttpLink({
// ...
}),
cache: new InMemoryCache({
// ..
}),
});
进一步,用户可以执行某些操作,这需要我为以前不存在的 apollo 客户端设置一些新的 headers。我最初想为此使用反应上下文来传递 set new headers 并在 <Apollo />
中使用它们,但我不确定这是否是正确的方法。
看了文档,好像apollo headers只能在初始化的时候设置?
您通常不想将 header 直接传递给您的 Apollo 客户端实例,而是希望利用 apollo-link-context
。您可以将实际的 header 值存储在内存、LocalStorage 或任何对您的应用程序有意义的地方。然后在发送之前使用 link 将它们注入到每个请求中:
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
可以异步。您传递给它的函数应该 return 一个带有您想要更改的任何上下文字段的 object,或者一个将解析为一个的 Promise:
const headerLink = setContext(async (request, previousContext) => {
const authorization = await someAsyncCall()
return {
headers: {
...previousContext.headers,
authorization,
},
}
});
您可以查看 the docs 以获取更多示例。
丹尼尔·里尔登是对的。然而,对于 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;
为了扩展 Daniel Rearden 的回答,如果您只想为特定的 query/mutation 添加 headers 而不是所有后续查询:
初始化阿波罗:
const httpLink = createHttpLink({
uri: '/graphql',
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
然后简单地将上下文添加到所需的 query/mutation 本身:
const {loading, data, error} = useQuery(QUERY_DEF, {
context: {
headers: {
"HeaderKey": "HeaderValue"
}
}
});
我的应用程序包含 <Apollo />
组件,该组件实质上是初始化客户端。
const client = new ApolloClient({
link: new HttpLink({
// ...
}),
cache: new InMemoryCache({
// ..
}),
});
进一步,用户可以执行某些操作,这需要我为以前不存在的 apollo 客户端设置一些新的 headers。我最初想为此使用反应上下文来传递 set new headers 并在 <Apollo />
中使用它们,但我不确定这是否是正确的方法。
看了文档,好像apollo headers只能在初始化的时候设置?
您通常不想将 header 直接传递给您的 Apollo 客户端实例,而是希望利用 apollo-link-context
。您可以将实际的 header 值存储在内存、LocalStorage 或任何对您的应用程序有意义的地方。然后在发送之前使用 link 将它们注入到每个请求中:
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
可以异步。您传递给它的函数应该 return 一个带有您想要更改的任何上下文字段的 object,或者一个将解析为一个的 Promise:
const headerLink = setContext(async (request, previousContext) => {
const authorization = await someAsyncCall()
return {
headers: {
...previousContext.headers,
authorization,
},
}
});
您可以查看 the docs 以获取更多示例。
丹尼尔·里尔登是对的。然而,对于 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;
为了扩展 Daniel Rearden 的回答,如果您只想为特定的 query/mutation 添加 headers 而不是所有后续查询:
初始化阿波罗:
const httpLink = createHttpLink({
uri: '/graphql',
});
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = localStorage.getItem('token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
然后简单地将上下文添加到所需的 query/mutation 本身:
const {loading, data, error} = useQuery(QUERY_DEF, {
context: {
headers: {
"HeaderKey": "HeaderValue"
}
}
});