GraphQL 字段未定义

Ant*_*jim 1 node.js graphql graphql-js

从 GraphQL / Node / Express / Typescript 堆栈开始,我遇到了一个问题,字段参数没有传递给解析器函数。我有两个疑问:

用户列表:

UserList: {
        type: new GraphQLList(UserType),
        args: {
            userName: {
                type: GraphQLString
            },
            userIsLocked: {
                type: GraphQLBoolean
            },
            userIsConfirmed: {
                type: GraphQLBoolean
            },
            userAwaitingPassword: {
                type: GraphQLBoolean
            }
        },
        resolve: ((_, {fields}) => new User().where({fields}))
    }
Run Code Online (Sandbox Code Playgroud)

和用户:

User: {
    type: UserType,
    args: {
        userId: {
            type: GraphQLID
        }
    },
    resolve: ((_, {userId}) => new User().getById({userId}))
}
Run Code Online (Sandbox Code Playgroud)

如果未提供条件,该User().where()函数默认显示所有用户。但是,请考虑以下查询和结果:

query All {
  UserList(userIsLocked:true){
    userId
    userName
    userIsLocked
  }
}

// Results
{
  "data": {
    "UserList": [
      {
        "userId": "a4f1d968-52d6-4148-bf62-1e132a4defde",
        "userName": "user1",
        "userIsLocked": false
      },
      {
        "userId": "b42a1170-096a-11e9-b568-0800200c9a66",
        "userName": "administrator",
        "userIsLocked": false
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

显然, userIsLocked 没有传递给where()函数的 fields 参数。但是,以下工作有效:

query Individual {
  User(userId: "a4f1d968-52d6-4148-bf62-1e132a4defde") {
    userId
    userName
    userIsLocked
  }
}

// Results
{
  "data": {
    "User": {
      "userId": "a4f1d968-52d6-4148-bf62-1e132a4defde",
      "userName": "user1",
      "userIsLocked": false
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

userId登录到 的请求时getById(),我{"userId":"a4f1d968-52d6-4148-bf62-1e132a4defde"}在控制台中看到。但是,当fields登录请求时where(),控制台中显示的只是undefined我的查询默认显示所有用户。我无法弄清楚为什么两个明显相同的查询会以如此不同的方式表现。我已经浏览了 GraphQL 的文档,但我能找到的只是示例查询和一般查询结构。

Dan*_*den 6

传递给函数的第二个参数resolve是一个对象,其属性映射到该字段的参数。让我们看看正在运行的解析器:

resolve: (_, {userId}) => new User().getById({userId})
Run Code Online (Sandbox Code Playgroud)

在这里,您使用对象解构语法从第二个参数解压userId属性并将其签名到同名的变量。然后,您可以使用简写属性名称语法来创建具有该userId属性的对象(具有您定义的变量的值userId),并将该对象传递给该getById方法。

这在语法上等价于以下函数:

resolve: (_, args) => {
  const userId = args.userId
  return new User().getById({ userId: userId })
}
Run Code Online (Sandbox Code Playgroud)

从你的问题中不清楚你正在使用什么 ORM,所以我无法判断你是否where在其他解析器中正确调用了该方法。但是,您绝对不会解压该字段的任何参数。这是你的函数:

resolve: (_, {fields}) => new User().where({fields})
Run Code Online (Sandbox Code Playgroud)

这相当于:

resolve: (_, args) => {
  const fields = args.fields
  return new User().where({ fields: fields })
}
Run Code Online (Sandbox Code Playgroud)

您的字段具有以下四个参数:userNameuserIsLockeduserIsConfirmed。不是一个有效的参数,因此将始终是未定义的,除非您将名为 fields 的参数添加到您的字段中并实际将其传入。我将冒险猜测并说您的模型也没有属性。如果您只想将参数对象传递给方法,您可以这样做:userAwaitingPasswordfieldsUserListfieldswhere

resolve: (_, fields) => new User().where(fields)
Run Code Online (Sandbox Code Playgroud)

请注意缺少花括号。同样,您没有告诉我们任何有关您正在使用的 ORM 或用户模型本身的信息,因此如果您没有正确使用API,这仍然可能无法给您带来所需的结果。但是,希望这能让您走上正轨。