GraphQL 解析器可以强制检索父对象中的参数吗?

Can a GraphQL resolver force arguments in parent to be retrieved?

如果我有 2 种类型:UserNote,具有以下架构:

query {
   getUser(userId: ID!): User
}

type User {
   userId: ID
   email: String
   notes: [Note]
}

type Note {
   noteId: ID
   text: String
}

我正在为 User#notes 编写解析器。现在说笔记需要通过电子邮件地址检索,所以我实际上需要传递给解析器的根对象包含 email 字段,无论如何我可以强制 GraphQL 查询中的 email 字段User 即使用户没有请求也对象?

在代码方面,来自 what I see,这就是我编写解析器的方式。每当用户请求 note 字段时,如何确保请求 obj.email

User:  {
  notes(obj, args, context, info) {
    // How can I ensure obj.email is requested?
    return NoteRetriever.getNotesByEmail(obj.email);
  }
}

编辑

我想知道除非明确请求,否则父解析器不解析 email 字段的情况。如果我们需要调用 API 来获取用户的电子邮件怎么办?所以默认情况下我们不要求它。但是,当请求注释时,也请求电子邮件是有意义的。

解析器是否可以指定对父字段的依赖性 - 以确保得到请求?

作为第一个参数传递给您的解析器的 "parent" 值正是在父字段的解析器中返回的值(除非返回了 Promise,在这种情况下它将是 Promise 解析的任何内容)。所以如果我们有这样的解析器:

Query: {
  getUser: () => {
    return {
      userId: 10,
      email: 'user@example.com',
      foobar: 42,
    }
  }
}

以及类似这样的查询:

query {
  getUser {
    id
    notes
  }
}

传递给我们的 notes 解析器的是我们在解析器内部为 getUser 返回的整个对象。

User:  {
  notes(obj, args, context, info) {
    console.log(obj.userId) // 10
    console.log(obj.email)  // "user@example.com"
    console.log(obj.foobar) // 42
  }
}

无论请求的字段如何,父值都是相同的,除非父字段解析器的逻辑实际上 returns 一个不同的值,具体取决于请求的字段。这意味着您还可以将任意数量的其他任意条目(如上面的 foobar)从父字段传递到每个子字段。

编辑:

字段是相互独立解析的,因此没有声明字段之间依赖关系的机制。如果 getUser 解析器正在查看请求的字段并根据请求的字段进行某些 API 调用(如果没有请求这些字段则忽略其他),那么您需要修改该逻辑以考虑对于需要 user 电子邮件的 notes 字段。

我认为期望是,如果您控制父级的查询,并期望子级中的值,您应该确保所需的值始终由父级解析。

但是,有一种方法可以在合并模式时执行您所要求的操作。这在此处描述 https://www.apollographql.com/docs/graphql-tools/schema-stitching.

基本上需要有一个类似于

的基本架构
type Query {
    getUser(userId: ID!): User
}

type User {
   userId: ID
   email: String
}

使用与现在相同的解析器,第二个模式类似于

type Note {
    noteId: ID
    text: String
}

extend type User {
    notes: [Note]
}

以及类似的东西

import { mergeSchemas } from 'graphql-tools';

const finalSchema = mergeSchemas({
    schemas: [userSchema, noteSchema],
    resolvers: {
        User {
            notes: {
                fragment: '... on User { email }',
                resolve: notesResolver
            }
        }
    }
});
console.dir(await graphql(finalSchema, `query { ... }`));

注意定义电子邮件字段的片段 属性。在上面的 link 中,它描述了当解析此子项时,这将如何强制解析父项上的给定字段。