GraphQL解析器可以强制在父级中检索参数吗?

时间:2019-03-25 16:08:16

标签: graphql graphql-js

如果我有两种类型: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开始的代码方面,这就是我编写解析器的方式。每当用户请求obj.email字段时,如何确保请求note

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

修改

我想知道,除非明确要求,否则父解析器不会解析email字段。如果我们需要进行API调用以获取用户电子邮件该怎么办?因此,默认情况下,我们不要求它。但是,当请求备忘时,也可以请求电子邮件。

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

2 个答案:

答案 0 :(得分:1)

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

但是,有一种方法可以完成合并架构时的要求。 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 { ... }`));

请注意定义电子邮件字段的片段属性。在上面的链接中,它描述了如何解决此子项时如何强制给定字段在父项上进行解析。

答案 1 :(得分:0)

作为第一个参数传递给解析器的“父”值正是在父字段的解析器中返回的值(除非返回了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
  }
}

父字段的值将是相同的,而与请求的字段无关,除非父字段解析器的逻辑实际上根据请求的字段返回不同的值。这意味着您还可以将任何其他任意条目(如上面的foobar)从父字段传递到每个子字段。

编辑:

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