GraphQL 解析器可以强制检索父对象中的参数吗?
Can a GraphQL resolver force arguments in parent to be retrieved?
如果我有 2 种类型:User
和 Note
,具有以下架构:
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 中,它描述了当解析此子项时,这将如何强制解析父项上的给定字段。
如果我有 2 种类型:User
和 Note
,具有以下架构:
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 中,它描述了当解析此子项时,这将如何强制解析父项上的给定字段。