GraphQL - 返回 null 的关系
GraphQL - Relationship returning null
我开始学习 GraphQL,我正在尝试创建以下关系:
type User {
id: ID!,
name: String!,
favoriteFoods: [Food]
}
type Food {
id: ID!
name: String!
recipe: String
}
所以基本上一个用户可以有很多喜欢的食物,一个食物可以是很多用户的最爱。我正在使用 graphql.js,这是我的代码:
const Person = new GraphQLObjectType({
name: 'Person',
description: 'Represents a Person type',
fields: () => ({
id: {type: GraphQLNonNull(GraphQLID)},
name: {type: GraphQLNonNull(GraphQLString)},
favoriteFoods: {type: GraphQLList(Food)},
})
})
const Food = new GraphQLObjectType({
name: 'Food',
description: 'Favorite food(s) of a person',
fields: () => ({
id: {type: GraphQLNonNull(GraphQLID)},
name: {type: GraphQLNonNull(GraphQLString)},
recipe: {type: GraphQLString}
})
})
这是食物数据:
let foodData = [
{id: 1, name: 'Lasagna', recipe: 'Do this then that then put it in the oven'},
{id: 2, name: 'Pancakes', recipe: 'If you stop to think about, it\'s just a thin, tasteless cake.'},
{id: 3, name: 'Cereal', recipe: 'The universal "I\'m not in the mood to cook." recipe.'},
{id: 4, name: 'Hashbrowns', recipe: 'Just a potato and an oil and you\'re all set.'}
]
因为我只是在尝试,所以我的解析器基本上只是 return 一个在解析器本身内部创建的用户。我的思考过程是:将食物 ID 放入 GraphQLList,然后从 foodData usind lodash 获取数据]函数find(),用找到的数据替换person.favoriteFoods中的值。
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
description: 'Root Query',
fields: {
person: {
type: Person,
resolve(parent) {
let person = {
name: 'Daniel',
favoriteFoods: [1, 2, 3]
}
foodIds = person.favoriteFoods
for (var i = 0; i < foodIds.length; i++) {
person.favoriteFoods.push(_.find(foodData, {id: foodIds[i]}))
person.favoriteFoods.shift()
}
return person
}
}
}
})
但最后的食物是 returning null。这是查询的结果:
query {
person {
name
favoriteFoods {
name
recipe
}
}
}
# Returns
{
"data": {
"person": {
"name": "Daniel",
"favoriteFoods": [
{
"name": "Lasagna",
"recipe": "Do this then that then put it in the oven"
},
{
"name": "Pancakes",
"recipe": "If you stop to think about, it's just a thin, tasteless cake."
},
null
]
}
}
}
是否可以仅使用其 ID return Food 类型的数据?或者我应该为此再做一个查询吗?在我看来,这种关系是有道理的,我认为我不需要在 foodData 中存储所有喜欢某种食物的用户的 ID,因为它有一个我可以使用的 ID获取数据,所以我看不出代码或其结构有问题。
在一个数组上调用 shift
和 push
,同时遍历同一个数组将不可避免地导致一些意想不到的结果。您可以复制数组,但使用 map
:
会容易得多
const person = {
name: 'Daniel',
favoriteFoods: [1, 2, 3],
}
person.favoriteFoods = person.favoriteFoods.map(id => {
return foodData.find(food => food.id === id)
})
return person
这里的另一个问题是,如果您的架构 return 是另一个解析器中的 Person
,则您也必须在该解析器中复制此逻辑。你真正应该做的只是return那个favoriteFoods: [1, 2, 3]
的人。然后为favoriteFoods
字段写一个单独的解析器:
resolve(person) {
return person.favoriteFoods.map(id => {
return foodData.find(food => food.id === id)
})
}
我开始学习 GraphQL,我正在尝试创建以下关系:
type User {
id: ID!,
name: String!,
favoriteFoods: [Food]
}
type Food {
id: ID!
name: String!
recipe: String
}
所以基本上一个用户可以有很多喜欢的食物,一个食物可以是很多用户的最爱。我正在使用 graphql.js,这是我的代码:
const Person = new GraphQLObjectType({
name: 'Person',
description: 'Represents a Person type',
fields: () => ({
id: {type: GraphQLNonNull(GraphQLID)},
name: {type: GraphQLNonNull(GraphQLString)},
favoriteFoods: {type: GraphQLList(Food)},
})
})
const Food = new GraphQLObjectType({
name: 'Food',
description: 'Favorite food(s) of a person',
fields: () => ({
id: {type: GraphQLNonNull(GraphQLID)},
name: {type: GraphQLNonNull(GraphQLString)},
recipe: {type: GraphQLString}
})
})
这是食物数据:
let foodData = [
{id: 1, name: 'Lasagna', recipe: 'Do this then that then put it in the oven'},
{id: 2, name: 'Pancakes', recipe: 'If you stop to think about, it\'s just a thin, tasteless cake.'},
{id: 3, name: 'Cereal', recipe: 'The universal "I\'m not in the mood to cook." recipe.'},
{id: 4, name: 'Hashbrowns', recipe: 'Just a potato and an oil and you\'re all set.'}
]
因为我只是在尝试,所以我的解析器基本上只是 return 一个在解析器本身内部创建的用户。我的思考过程是:将食物 ID 放入 GraphQLList,然后从 foodData usind lodash 获取数据]函数find(),用找到的数据替换person.favoriteFoods中的值。
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
description: 'Root Query',
fields: {
person: {
type: Person,
resolve(parent) {
let person = {
name: 'Daniel',
favoriteFoods: [1, 2, 3]
}
foodIds = person.favoriteFoods
for (var i = 0; i < foodIds.length; i++) {
person.favoriteFoods.push(_.find(foodData, {id: foodIds[i]}))
person.favoriteFoods.shift()
}
return person
}
}
}
})
但最后的食物是 returning null。这是查询的结果:
query {
person {
name
favoriteFoods {
name
recipe
}
}
}
# Returns
{
"data": {
"person": {
"name": "Daniel",
"favoriteFoods": [
{
"name": "Lasagna",
"recipe": "Do this then that then put it in the oven"
},
{
"name": "Pancakes",
"recipe": "If you stop to think about, it's just a thin, tasteless cake."
},
null
]
}
}
}
是否可以仅使用其 ID return Food 类型的数据?或者我应该为此再做一个查询吗?在我看来,这种关系是有道理的,我认为我不需要在 foodData 中存储所有喜欢某种食物的用户的 ID,因为它有一个我可以使用的 ID获取数据,所以我看不出代码或其结构有问题。
在一个数组上调用 shift
和 push
,同时遍历同一个数组将不可避免地导致一些意想不到的结果。您可以复制数组,但使用 map
:
const person = {
name: 'Daniel',
favoriteFoods: [1, 2, 3],
}
person.favoriteFoods = person.favoriteFoods.map(id => {
return foodData.find(food => food.id === id)
})
return person
这里的另一个问题是,如果您的架构 return 是另一个解析器中的 Person
,则您也必须在该解析器中复制此逻辑。你真正应该做的只是return那个favoriteFoods: [1, 2, 3]
的人。然后为favoriteFoods
字段写一个单独的解析器:
resolve(person) {
return person.favoriteFoods.map(id => {
return foodData.find(food => food.id === id)
})
}