graphql-js 查询可以按任何顺序,但显然输入类型不能

graphql-js Queries can be in any order, but apparently input types cannot

正在尝试跟踪 example 嵌套突变:

看起来 graphql-js 我可以为查询提供前向引用,但不能为突变提供前向引用。

例如,如果我有两个类型,PersonUser,查询具有前向引用是合法的:

const UserType = new graphql.GraphQLObjectType({
  name: 'UserType',
  description: 'A user',
  fields: () => ({
    uuid: {type: (graphql.GraphQLString)},
    person: {
      type: PersonType,
      resolve: (root, {args}, request ) => {
        return db.personGetByUUID(request.user, root.person);
      }
    },
  })
});
const PersonType = new graphql.GraphQLObjectType({ [...]

但是这个前向引用对于突变是不合法的:

const UserInputType = new graphql.GraphQLInputObjectType({
  name: 'UserInputFields',
  description: 'input type for creation or update of a user',
  fields: {
    uuid: {type: (graphql.GraphQLString)},
    person: {type: (PersonInputType)},
  }
});

const PersonInputType = new graphql.GraphQLInputObjectType({ [...]

如果我尝试这样做,我会得到错误 ReferenceError: PersonInputType is not defined

我的理解是 GraphQL 允许您从图中的任何节点开始并创建逻辑树视图以查询或改变图。这似乎适用于查询,但不适用于突变。

这是缺少的功能,Javascript 的限制,还是我做错了什么?

其实你可以。

GraphQL 类型上的 fields 属性 可以是对象,也可以是 returns 对象的函数。当您需要引用尚未定义的类型时,只需将整个 field 对象包装在一个函数中即可。就像你在定义 UserType.

时所做的一样
const UserInputType = new graphql.GraphQLInputObjectType({
  name: 'UserInputFields',
  description: 'input type for creation or update of a user',
  fields: () => ({ // <----------- function that returns the object
    uuid: {type: (graphql.GraphQLString)},
    person: {type: (PersonInputType)},
  })
});

const PersonInputType = new graphql.GraphQLInputObjectType({ [...]

引自docs

When two types need to refer to each other, or a type needs to refer to itself in a field, you can use a function expression (aka a closure or a thunk) to supply the fields lazily.