GraphQL解析器能否强制检索父级中的参数?

GraphQL解析器能否强制检索父级中的参数?,graphql,graphql-js,Graphql,Graphql Js,如果我有两种类型:User和Note,模式如下: 查询{ getUser(userId:ID!):User } 类型用户{ userId:ID 电子邮件:String 注:[注] } 字条{ 注ID:ID 文本:字符串 } 我正在为User\notes编写一个解析器。现在假设注释需要通过电子邮件地址检索,那么我实际上需要传递给解析器的根对象包含电子邮件字段,是否可以强制GraphQL查询用户对象中的电子邮件字段,即使用户没有请求它 在代码方面,从,这是我如何编写解析器。我如何确保每当用户请求备

如果我有两种类型:
User
Note
,模式如下:

查询{
getUser(userId:ID!):User
}
类型用户{
userId:ID
电子邮件:String
注:[注]
}
字条{
注ID:ID
文本:字符串
}
我正在为
User\notes
编写一个解析器。现在假设注释需要通过电子邮件地址检索,那么我实际上需要传递给解析器的根对象包含
电子邮件
字段,是否可以强制GraphQL查询
用户
对象中的
电子邮件
字段,即使用户没有请求它

在代码方面,从,这是我如何编写解析器。我如何确保每当用户请求
备注
字段时,都会请求
obj.email

用户:{
注释(对象、参数、上下文、信息){
//我如何确保请求obj.email?
返回NoteRetriever.getNotesByMail(obj.email);
}
}
编辑

我想知道的是,除非明确要求,否则父解析程序不会解析
电子邮件
字段。如果我们需要进行API调用以获取用户的电子邮件,该怎么办?因此,默认情况下,我们不会请求它。然而,当要求提供笔记时,也可以要求发送电子邮件

冲突解决程序是否有办法指定对父字段的依赖关系-以确保得到请求?

作为第一个参数传递给冲突解决程序的“父”值正是在父字段的冲突解决程序中返回的值(除非返回了承诺,在这种情况下,它将是承诺解析为的内容)。如果我们有这样一个解析器:

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
  }
}
无论请求的字段是什么,父值都是相同的,除非父字段解析程序的逻辑根据请求的字段实际返回不同的值。这意味着您还可以将任意数量的其他任意条目(如上面的
foobar
)从父字段传递到每个子字段

编辑:


字段彼此独立解析,因此没有声明字段之间依赖关系的机制。如果
getUser
解析器正在查看请求的字段并基于请求的字段进行某些API调用(如果未请求这些字段,则忽略其他字段),然后,您需要修改该逻辑,以说明需要
用户
电子邮件的
注释
字段。

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

然而,在合并模式时,有一种方法可以满足您的要求。这里描述了这一点

基本上需要有一个基本的模式

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 { ... }`));
使用与现在相同的解析器,以及类似于

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 { ... }`));
以及类似于

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 { ... }`));

注意定义email字段的fragment属性。在上面的链接中,它描述了在解析此子项时,如何强制父项解析给定字段。

感谢您的回复。我想知道的是,除非明确要求,否则父解析器不会解析电子邮件字段。如果我们需要进行API调用以获取用户的电子邮件,该怎么办?因此,默认情况下,我们不会请求它。但是,当请求
notes
时,也可以请求
email
。您需要在
getUser
解析器中处理该逻辑。请看我的编辑。谢谢回复!我也遇到过这个。是的,这正是我想要的,但似乎这只能发生在进行模式缝合时,而不是在普通解析器定义中。你是100%正确的,它只能发生在缝合过程中,这是一个痛苦的开销