使用Apollo Client的方式,在GraphQL中将会话信息存储到请求头
总结
突然話が変わりますが、皆さんはSPAなどでGraphQLを使う際、リクエストURLのクエリ文字やGraphQLのinput部分にセッション情報を含めていることがありませんか?
実は、私もGraphQLを始めたばかりの頃は、実際にセッション情報の一部をリクエストURLのクエリ文字に含めて、バックエンドにログインしているような使い方をしていました。
※ 因为我们正在使用NextAuth,所以会话信息是由前端而不是后端来保存。
NextAuth有一个名为useSession的钩子函数来管理会话。通过使用它,我们将摆脱在Redis设置和Cookie周围遇到的困难,即“在后端管理会话”的情况。
这是NextAuth的官方网站,请如果你感兴趣的话,去看一下!
回到主题,本次我们将一边进行实际的Apollo Client初始设置,一边进行解说。
安装Apollo Client
$ npm install @apollo/client graphql
在这里,我们正在安装两个软件包:1. @apollo/client和2. graphql*。
第一个软件包(@apollo/client)是使用apollo客户端所需的基本内容的大致汇总。
例如,据说它包含了Apollo Client中的代表性缓存机制InMemoryCache、错误处理和本地状态管理等。
两个包(graphql)是解析GraphQL查询所需的。
初始化Apollo Client实例
这里包括了将会话信息添加到详细的标头中的部分,但是由于分离这些内容比较麻烦,所以我们将一并解释。
// 1. 必要なシンボルのimport
import {
ApolloClient,
InMemoryCache,
createHttpLink,
ApolloProvider,
} from "@apollo/client";
// 2. http linkの生成
const httpLink = createHttpLink({
uri: `${server url}/graphql`,
});
// 3. headerをリクエストを送る前のコンテキストに追加する
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
return {
headers: {
...headers,
authorization: token && token !== 'undefined' ? token : "",
}
}
})
// 4. apollo clientのインスタンスの初期化
const apolloClient = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
在代码中,我用注释简略地描述了”在做什么”,但我打算再详细解释一下。
由于第一部分只是一个简单的导入,我将略去不予翻译。
2. 生成HTTP链接
在这里,我们正在创建用于向后端发送请求的请求URL。
在本示例代码中,我们通过“从LocalStrage中获取存储的JWT令牌并将其添加到标头中”的步骤来执行此操作,因此我们将生成请求URL的部分与创建标头的部分分开。但是,看起来还有一种将标头一起传递的方法,如下所示。
我试着使用Apollo Client创建了一个GitHub客户端。
const httpLink = createHttpLink({
uri: "https://api.github.com/graphql",
headers: {
authorization: `Bearer ${process.env.REACT_APP_GITHUB_TOKEN}`
}
});
3. 创建标题部分
在这里,我们使用一个名为setContext的函数来设置上下文。
看起来这个setContext函数接收一个返回对象或者Promise的函数作为参数,并返回一个用于设置请求新内容(在这里是header)的对象。
此外,根据报道,setContext函数的参数基本上接受两个参数,第一个参数是“即将执行的GraphQL请求”,第二个参数是“请求之前的上下文”。
由于似乎必须接受两个参数,我将第一个参数用下划线_保留,而只接受从第二个参数开始的header。(基本上除了第一个参数和header之外不需要其他参数)
此外,如上所述,本次我們將JWT令牌保存在localStorage中,然後提取出來並添加到標頭中。
4. 初始化 Apollo Client 实例
使用2.和3.创建的请求URL和头部信息进行连接,然后将其作为参数传递给实例进行初始化。通过这样的方式,如果Apollo Client被创建成功,就可以使用ApolloProvider在其他组件中共享客户端信息。
<ApolloProvider client={apolloClient}>
<Component {...pageProps} />
</ApolloProvider>
最后
如果有任何错误或可以指出的地方,请随意评论!?♀️
请提供以下中文短句的本地化的释义:
-
- Apollo Clientを使ってGitHubクライアントを作成してみた
- Apollo client公式