GraphQL 查询和对象字段之间的编程区别是什么?

What's the programmatic difference between a GraphQL query and an Object field?

有谁知道我如何以编程方式区分 graphql 查询和字段?我在说这个:

type User {
  id: ID! <-- this would be a field
}

type Query {
  getUsers: [User]! <-- this would be a query 
}

我试图从各个方面来看待它,但它们几乎完全相同,都是 FieldDefinition 类型并且具有完全相同的结构。那么有没有办法做到这一点?我正在尝试编写一个适用于两者并且非常相似的 auth schema directive ,但是如果将指令应用于查询,它应该做一件事不同。

如果所有其他方法都失败了,我可以创建两个单独的指令,但如果可以重复使用同一个指令并且它的使用者不必担心它被应用到哪里,那就太好了,它只是工作.

在查看了所有可能的控制台日志之后,我想我可能已经找到了,所以如果有人感兴趣:

一个名为 getUsers 的查询,如果这样定义:

type Query {
  getUsers: [User]!
}

parentTypeQuery。与突变类似,parentTypeMutation。您可以通过以下方式在解析器(或扩展解析器的指令)中访问它:

async function resolver(parent, args, context, info) {
  // will be "Query" for queries and `Mutation` for mutations, 
  // and the parent object for anything else, ex. "User" for `type User {}`

  console.log(info.parentType) 
}

需要进一步调查,看看它是否适用于所有场景,但理论上它应该适用。如果我发现该方法有任何问题,我会 post 发表评论。

GraphQL 支持三种类型的操作——查询、变更和订阅。单个模式必须支持查询,但其他两种类型是可选的。对于模式确实支持的每个操作,它定义了一个类型作为该操作的 root。我们将这三种类型称为根操作类型。按照惯例,我们通常将这些类型命名为 QueryMutationSubscription,但它们也可以有任何其他名称。

如果使用 SDL,我们指定与每个操作关联的类型,如下所示:

schema {
  query SomeType
  mutation SomeOtherType
}

如果您使用的是 Apollo Server,则上述步骤不是必需的,但可以覆盖 Apollo 提供的默认设置。

如果您使用的是普通 GraphQL.js,那么根操作类型将定义为您的架构对象的一部分:

const schema = new GraphQLSchema({
  query: SomeType,
  mutation: SomeOtherType,
})

因为 QueryMutation 和其他对象类型一样,重要的是要记住 Query 上的字段(如 getUsers 仍然只是一个字段) .通俗地说,我们将这些字段称为查询(将突变根类型上的字段称为突变),但它们仍然只是字段。

但是,给定一个 GraphQLResolveInfo 对象,您可以识别字段属于哪种类型,还可以识别三种根操作类型。所以你可以这样做:

const { parentType, schema } = info
const isQueryField = parentType === schema.getQueryType()