我是graphQL和mongoDB的新手,我正在尝试使其在我的项目中工作。问题在于GraphiQL中来自查询的数据与客户端内部来自同一查询的数据完全不同。这是我的架构设置:
const graphql = require('graphql');
const _ = require('lodash');
const Item = require('../models/item');
const {
GraphQLObjectType,
GraphQLString,
GraphQLSchema,
GraphQLID,
GraphQLInt,
GraphQLList
} = graphql;
const ItemType = new GraphQLObjectType({
name: 'Item',
fields: () => ({
name: {
type: GraphQLString
},
id: {
type: GraphQLID
},
description: {
type: GraphQLString
},
price: {
type: GraphQLInt
},
image: {
type: GraphQLString
},
category: {
type: GraphQLString
}
})
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
item: {
type: ItemType,
args: {
id: {
type: GraphQLID
}
},
resolve(parent, args) {
// code to get data from db / other source
return Item.findById(args.id);
}
},
items: {
type: new GraphQLList(ItemType),
resolve(parent, args) {
return Item.find({})
}
}
}
});
当我从graphiQL进行查询时,我收到的所有项目和数据都是“正确的”。看起来像这样:
当我从前端执行相同的确切查询时: 从“ apollo-boost”导入{gql};
const getItemsQuery = gql`
{
items {
name
id
description
price
image
category
}
}
`;
export { getItemsQuery };
它似乎一遍又一遍地重复第一个项目,我不知道为什么。 DB也显示了正确的项目。我的服务器端代码可以在这里找到:https://github.com/KamilStaszewski/shoppy/tree/adding_graphQL/server
答案 0 :(得分:3)
来自the docs:
InMemoryCache通过将结果拆分为单个对象,为每个对象创建唯一的标识符并将这些对象存储在扁平化的数据结构中,从而在将数据保存到存储之前对数据进行规范化。默认情况下,InMemoryCache将尝试使用id和_id的常见主键作为唯一标识符(如果它们与__typename一起存在于对象上)。
换句话说,Apollo将同时使用__typename
和id
为您提取的每个Item
创建一个缓存密钥。该密钥用于从缓存中获取适当的项目。问题是您的商品的null
返回了id
。这将导致每个项目都使用相同的键写入。结果,当您的查询结果从缓存中返回时,它会为您的items
数组中的每个项目查找相同的键。
要解决此问题,您需要确保您的API返回id
的值。我使用猫鼬的工作还不多,但是我认为,由于猫鼬会根据id
自动为您添加一个_id
字段,因此只需从您的猫中删除id
猫鼬模型(不是您的GraphQL类型)。或者,您可以尝试在GraphQL类型的id
字段中添加一个resolve函数:
resolve: (item) => item._id.toString()