【问题标题】:GraphQL custom Scalar validationGraphQL 自定义标量验证
【发布时间】:2020-10-21 13:11:36
【问题描述】:

我刚刚为 Node 制作了一个简单的标量类型/包,graphql-scalar-json5

在我看来工作正常

但我有一个问题

似乎使用它绕过了类型检查而不是使用输入类型?

这让我觉得我可能做错了什么。

当您收到错误时,在解决时,如果该值无效。
GraphiQL 中没有警告

我不确定这是否是 GraphQL 中自定义标量类型的限制。 或 GraphiQL 实现细节

在第一印象中,如果 JSON5(或 JSON)值有效地从 String 类型派生,但我从未告诉过 'GraphQL' 这件事,而且似乎不是这样做的方式,这是有道理的。 .
工具如何知道参数类型错误?

graphql-scalars获取另一个自定义标量EmailAddress

使用以下查询定义

echoMail(email: EmailAddress): EmailAddress

同样,类型检查仅在运行时/解析器时发生,因为它需要由解析器解析,以进行验证。

有没有更好的方法来做到这一点?

举个例子,给定如下实现

class MyScalar {
  constructor(value) {
    this.value = value;
  }
  toString() {
    return this.value;
  }
  static from(value) {
    if (typeof value !== "string")
      throw new Error(`Expected 'String' but got '${typeof value}'`);
    return new MyScalar(value);
  }
}
new GraphQLScalarType({
  name: "MyScalar",
  serialize: (x) => x.toString(),
  parseValue: MyScalar.from,
  parseLiteral: (ast, variables) =>
    Kind.VARIABLE
      ? (variables && MyScalar.from(variables[ast.name.value])) || undefined
      : MyScalar.from(ast.value),
});

你会如何改进它?
在哪里验证值有什么不同吗?
serializeparseValueon parseLiteral 上? 还有什么要“实施”的吗?

谢谢

【问题讨论】:

    标签: node.js graphql graphql-js


    【解决方案1】:

    自定义类型/标量...显然您需要自定义验证。

    在后端/API 上:

    parseValueparseLiteral 都被 MyScalar.from 包围。

    已经“接受”(验证“输入”)值通常不需要额外验证“输出”(serialize)。有时您可以使用它来“更正”数据/格式/值,但您可能会在解析器级别执行此操作(读取 DB - 在返回应该匹配类型 [-s] 的数据之前)。

    在 graphiQL/操场上:

    AFAIK 无法通知系统如何验证您的自定义类型/标量 - 根本无法支持。

    在前端:

    在发送自定义数据(变量)之前,您必须(应该)实施相同的验证(等同于在 API/后端上使用)规则。

    【讨论】:

    • 您的回答很有用,尝试过投票,但由于某种原因停留在 0 上,谢谢
    • @Dan 可能有人同时否决了它(+8 计数);)
    【解决方案2】:

    GraphiQL 等工具利用introspection 来获取有关正在执行请求的架构的信息。在后台,自省结果被转换为模式的本地副本,这用于验证在编辑器中编写的查询并提供自动完成建议。换句话说,当您打错字并且 GraphiQL 以红色突出显示它时,它会通过在本地验证查询而不是将请求发送到服务器来实现。

    这里的关键是 GraphiQL 架构不是可执行的——它不包含您用来编写架构的任何自定义代码。它具有与您的远程模式相同的类型,但它不包含这些类型使用的任何自定义代码(如解析器),因为该信息无法通过自省进行通信。因此,当您的查询由本地模式验证时,它无法知道自定义标量值是否有效,因为它无法运行代码来验证它们。这与 IntString 这样的内置标量形成对比,架构 可以 验证这些标量,因为它具有验证它们的代码,因为它们是内置的 :)

    这是您不想使用自定义标量的几个原因之一,除非绝对必要 - 它们无法通过客户端、编辑器插件等进行验证。

    【讨论】:

    • > 因为它们是内置的 :)
    猜你喜欢
    • 2020-08-03
    • 2018-05-29
    • 2020-01-18
    • 2018-02-12
    • 2022-08-05
    • 2020-06-26
    • 1970-01-01
    • 2014-12-24
    • 2020-08-03
    相关资源
    最近更新 更多