Apollo GraphQL查询缺失字段问题求助(React+F#后端)
问题根源
先看看你提供的服务器原始响应:
{"data":"{"stories":[{"name":"Story1","__typename":"Story"},{"name":"Story2","__typename":"Story"},{"name":"Story3","__typename":"Story"}]}"}
这里的核心问题是:服务器返回的data字段是一个JSON字符串,而不是Apollo客户端期望的已解析的JSON对象。
Apollo客户端会直接尝试访问response.data.stories,但此时response.data只是一串文本字符串,字符串本身并没有stories属性,所以才会抛出「Missing field stories」的错误。这种情况一般是F#后端在序列化响应时多做了一次JSON编码导致的——本该直接返回结构化对象,结果把整个data内容又转成了字符串。
解决方案
方案1:修复F#后端的响应序列化(推荐)
这是最根本的解决方式,确保后端输出符合GraphQL标准的响应格式:
- 检查你的F# GraphQL服务(比如使用GraphQL.NET或Fable.GraphQL)的序列化逻辑,不要手动对
data字段做JSON序列化,让框架自动处理完整的响应输出 - 确保最终返回的JSON结构是
{"data": {...}},其中data是一个对象,而非字符串
方案2:在Apollo客户端添加临时拦截器修复
如果暂时无法修改后端代码,可以在Apollo客户端配置中添加响应拦截器,手动解析嵌套的JSON字符串:
const client = new ApolloClient({ uri: '/graphql', // 添加响应拦截器,处理嵌套的JSON字符串 responseInterceptor: async (response) => { // 检测data是否为字符串类型,若是则解析为JSON对象 if (typeof response.data === 'string') { response.data = JSON.parse(response.data); } return response; }, }); client .query({ query: gql` query testStoryQuery { stories { name } } ` }) .then(result => console.log(result));
这个拦截器会在Apollo客户端处理响应前,把嵌套的JSON字符串解析成对象,之后客户端就能正常找到stories字段了。
验证修复效果
修复完成后,服务器返回的正确响应格式应该是:
{"data":{"stories":[{"name":"Story1","__typename":"Story"},{"name":"Story2","__typename":"Story"},{"name":"Story3","__typename":"Story"}]}}
此时response.data直接是包含stories数组的对象,Apollo客户端就能正常处理查询结果了。
内容的提问来源于stack exchange,提问作者John Johnson

