【问题标题】:How to trigger visitInputObject method on custom directive?如何在自定义指令上触发 visitInputObject 方法?
【发布时间】:2020-06-16 10:30:28
【问题描述】:

我正在构建一个自定义指令,希望在其中验证整个输入对象。我在SchemaDirectiveVisitor 扩展类上使用INPUT_OBJECT 类型和visitInputObject 方法。

每次我使用输入类型运行突变时,visitInputObject 都不会运行。 我使用了其他类型/方法,例如 visitObjectvisitFieldDefinition,它们运行良好。但是当尝试使用输入类型和方法时,它们不会触发。

我已阅读我能找到的所有可用文档。这还不支持吗?

一些上下文代码(不是实际的):

directive @validateThis on INPUT_OBJECT

input MyInputType @validateThis {
  id: ID
  someField: String
}
type Mutation {
  someMutation(myInput: MyInputType!): SomeType
}
class ValidateThisDirective extends SchemaDirectiveVisitor {
  visitInputObject(type) {
    console.log('Not triggering');
  }
}

【问题讨论】:

    标签: graphql apollo apollo-server graphql-tools


    【解决方案1】:

    SchemaDirectiveVisitor 的所有访问方法都是同时运行的——在构建模式时。这包括visitFieldDefinitionvisitFieldDefinition。不同的是,我们在使用visitFieldDefinition的时候,经常会修改访问字段的resolve函数。执行过程中调用的就是这个函数。

    您使用每个访问方法来修改相应的架构元素。您可以使用visitInputObject 修改输入对象,例如从中添加或删除字段。您不能使用它来修改输出对象字段的解析逻辑。你应该使用visitFieldDefinition

    visitFieldDefinition(field, details) {
    const { resolve = defaultFieldResolver } = field
      field.resolve = async function (parent, args, context, info) {
        Object.keys(args).forEach(argName => {
          const argDefinition = field.args.find(a => a.name === argName)
          // Note: you may have to "unwrap" the type if it's a list or non-null
          const argType = argDefinition.type
          if (argType.name === 'InputTypeToValidate') {
            const argValue = args[argName]
            // validate here
          } 
        })    
    
        return resolve.apply(this, [parent, args, context, info]);
      }
    }
    

    【讨论】:

    • 感谢您的回复。所以输入类型字段似乎没有解析方法?那么我如何对整个输入对象进行验证呢?使用visitObject,它允许我编辑字段的解析方法,然后从我传递的解析方法的第一个参数中获取整个类型对象字段值。
    • 是的,只有字段被解析——解析器被执行以生成响应中返回的值。输入的解析器没有意义——它们的值已经提供。就像我说的,您需要使用visitFieldDefinition(或visitObject)并修改解析器逻辑以包含验证逻辑。如果您只想对特定类型的参数进行验证,您可以检查字段对象以确定其参数的类型。
    • 对,有道理。我被卡住的部分是我并没有试图在它的出路时验证它,而是在它从输入的路上验证它。据我所知,visitObject 用于传出数据。我在想可能有一种方便的方式来验证方式,类似于它在出路时的方式,但听起来你可以做的唯一验证是类型检查,最多类型检查针对单个字段的自定义标量.感谢您的澄清!
    • @FunToCodeJavascript 也许我解释得不够充分。您可以在运行解析器代码之前进行验证。我用一个粗略的例子编辑了这个问题。顺便说一句,您可以使用自定义标量,但通常最好将验证逻辑放在业务层中,而不是 API 层的一部分——这样更可重用。
    • 哦,我误会了。想到代码可以运行时,数据已经在我的数据库中,但如果我在field.resolve 中验证并停止它,它实际上会阻止突变解析器启动。我已经把它写下来了,感谢您一直以来的帮助,我为吸收而道歉。我很高兴能使用它。
    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2013-08-17
    • 2019-08-05
    • 2018-06-13
    • 2017-01-02
    相关资源
    最近更新 更多