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获取数据,所以我看不出代码或其结构有问题。

在一个数组上调用 shiftpush,同时遍历同一个数组将不可避免地导致一些意想不到的结果。您可以复制数组,但使用 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)
  })
}