gpt4 book ai didi

SSR getServerSideProps 上的 Next.js graphql 上下文为空 {}

转载 作者:行者123 更新时间:2023-12-04 12:32:21 25 4
gpt4 key购买 nike

我有带有 getServerSideProps 的页面:

export const getServerSideProps: GetServerSideProps = async (ctx) => {
const apolloClient = initializeApollo()

await apolloClient.query({
query: UserQuery,
variables: { id: Number(ctx.query.id) },
})

return {
props: { initialApolloState: apolloClient.cache.extract() },
}
}
和用户的解析器:
resolve: async (_parent, { where }, ctx, info) => {
const select = new PrismaSelect(info).value

console.log(ctx) // {} why is empty when i use getServerSideProps?

const res = await ctx.db.user.findOne({
where: { id: 1 },
...select,
})

return null
},
相同的客户端查询工作正常,但出于某种原因,当我使用 getServerSideProps 时ctx 为空。如何解决这个问题?
我可以将 ctx 传递给 const apolloClient = initializeApollo(null, ctx) ,但它不会运行带有 db 属性的 apolloServer ctx 解析器函数,并且 ctx.db 将是未定义的。

阿波罗服务器:
const apolloServer = new ApolloServer({
schema,
async context(ctx: Ctx): Promise<Ctx> {
ctx.db = prisma

return ctx
},
})

export const apolloServerHandler = apolloServer.createHandler({ path: '/api/graphql' })
Apollo-客户:
import { useMemo } from 'react'
import { ApolloClient, InMemoryCache, NormalizedCacheObject } from '@apollo/client'
import { IncomingMessage, ServerResponse } from 'http'

type ResolverContext = {
req?: IncomingMessage
res?: ServerResponse
}

const typePolicies = {
Test: {
keyFields: ['id'],
},
User: {
keyFields: ['id'],
},
}

let apolloClient: ApolloClient<NormalizedCacheObject>

function createIsomorphLink(context: ResolverContext = {}): any {
if (typeof window === 'undefined') {
const { SchemaLink } = require('@apollo/client/link/schema')
const { schema } = require('backend/graphql/schema')
return new SchemaLink({ schema, context })
} else {
const { HttpLink } = require('@apollo/client/link/http')
return new HttpLink({
uri: '/api/graphql',
credentials: 'same-origin',
})
}
}

function createApolloClient(context?: ResolverContext): ApolloClient<NormalizedCacheObject> {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: createIsomorphLink(context),
cache: new InMemoryCache({ typePolicies }),
})
}

export function initializeApollo(
initialState: any = null,
// Pages with Next.js data fetching methods, like `getStaticProps`, can send
// a custom context which will be used by `SchemaLink` to server render pages
context?: ResolverContext
): ApolloClient<NormalizedCacheObject> {
const _apolloClient = apolloClient ?? createApolloClient(context)

// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// get hydrated here
if (initialState) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract()
// Restore the cache using the data passed from getStaticProps/getServerSideProps
// combined with the existing cached data
_apolloClient.cache.restore({ ...existingCache, ...initialState })
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient

return _apolloClient
}

// eslint-disable-next-line
export function useApollo(initialState: any): ApolloClient<NormalizedCacheObject> {
const store = useMemo(() => initializeApollo(initialState), [initialState])
return store
}

最佳答案

您需要应用上下文解析器:

async contextResolver(ctx: Ctx): Promise<Ctx> {
ctx.db = prisma

return ctx
},

const apolloServer = new ApolloServer({
schema,
context: contextResolver,
})
在 getServerSideProps 中:
export const getServerSideProps: GetServerSideProps = async (ctx) => {
await contextResolver(ctx)
const apolloClient = initializeApollo(null, ctx)

await apolloClient.query({
query: UserQuery,
variables: { id: Number(ctx.query.id) },
})

return {
props: { initialApolloState: apolloClient.cache.extract() },
}
}

关于SSR getServerSideProps 上的 Next.js graphql 上下文为空 {},我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64537328/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com