我有一个Nest + Graphql的后台
*和me
解析器:
@Query(() => User)
@UseGuards(JwtAuthGuard)
me(@Context() { req }) {
return this.usersService.findOne(req.user.id);
}
*在前端,我使用Nextjs、Apollo客户端和code-gen:
# codegen.yml
overwrite: true
schema: 'http://localhost:3030/graphql'
documents: 'src/graphql/**/*.gql'
generates:
src/graphql/index.tsx:
plugins:
- 'typescript'
- 'typescript-operations'
- 'typescript-react-apollo'
config:
reactApolloVersion: 3
*和with-next-apollo
封装
// utils/withApollo.ts
import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client'
import { getCookie } from 'cookies-next'
import withApollo from 'next-with-apollo'
export default withApollo(
({ initialState, ctx }) => {
const token = getCookie('token', ctx)
return new ApolloClient({
uri: 'http://localhost:3030/graphql',
cache: new InMemoryCache().restore(initialState || {}),
credentials: 'include',
headers: {
authorization: token ? `Bearer ${token}` : '',
},
})
},
{
render: ({ Page, props }) => {
return (
<ApolloProvider client={props.apollo}>
<Page {...props} />
</ApolloProvider>
)
},
}
)
*并像这样使用它:
import { useMeQuery } from '@/graphql/_generated'
import withApollo from '@/utils/withApollo'
import { getDataFromTree } from '@apollo/client/react/ssr'
const Home = () => {
const { loading, error } = useMeQuery()
...
}
export default withApollo(Home, { getDataFromTree }) // server side
// export default withApollo(Home) // client side
因此,即使我指定了一个页面为ssr,我的graphql解析器在后端受到jwt(@Query(() => User)
)的保护,也不会调用ssr,它只会调用客户端,我在网络选项卡中清楚地看到。
如果我在一个ssr页面中调用多个解析器,jwt保护的解析器在客户端调用,其他解析器在服务器上(如预期)
// they all expected to run on the server, bcs page is ssr
// jwt protected(only calling on the client)
const {} = useMeQuery()
const {} = useUserDetailsQuery()
// not protected(working fine)
const {} = useProductsQuery()
const {} = useBlogsQuery()
export default withApollo(ThisPage, { getDataFromTree }) // ssr
1条答案
按热度按时间nom7f22z1#
我不确定这是不是真的,但值得一查。对于每个应用程序,Apollo通常会创建一个新的
ApolloClient
示例。在某些情况下,在SSR期间(通常是由于错误的配置),在服务器端创建的ApolloClient
对于所有请求都保持不变。也就是说,与每个浏览器框架的新应用程序不同,服务器被认为是一个应用程序,因此只需要一个ApolloClient
示例。一旦默认的缓存选项强制客户端为相同的查询返回相同的数据(如果它们被缓存),有时会导致解析器不被调用。要检查是否是这种情况,您可以尝试完全禁用缓存并查看是否发生了更改。如果它被证明是问题的根源,那么创建
ApolloClient
的逻辑应该改变为您的应用为每个请求创建新的ApolloClient
示例的方式。