GraphQL 自定义标量验证

GraphQL custom Scalar validation

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

在我看来,一切正常

但是我有一个问题

seems like using this bypasses type-checking as opposed to using an input type?

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

当您收到错误时,在解决时,如果值无效。
GraphiQL

中没有警告

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

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

graphql-scalars

获取另一个自定义标量 EmailAddress

使用以下查询定义

echoMail(email: EmailAddress): EmailAddress

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

有更好的方法吗?

例如,给出以下实现

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 上? 'implement' 还有什么吗?

谢谢

自定义 type/scalar ...显然您需要自定义验证。

在 backend/API 上:

parseValueparseLiteral 都被 MyScalar.from 四分之一。

已经“接受”(已验证 'on input')的值通常不需要额外验证 'on output' (serialize)。它接缝你有时可以用它来“纠正” data/format/value 但你可能会在解析器级别上这样做(读取数据库 - 在返回应该匹配类型 [-s] 的数据之前)。

在 graphiQL/playground 上:

AFAIK 无法通知系统如何验证您的自定义 types/scalars - 根本无法支持。

在前端:

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

像 GraphiQL 这样的工具利用 introspection 来获取关于正在执行请求的模式的信息。在引擎盖下,内省结果被转换为您的模式的本地副本,这是用于验证在编辑器中编写的查询并提供自动完成建议的内容。换句话说,当您输入错误并且 GraphiQL 为您突出显示为红色时,它通过在本地验证查询而不是将请求发送到服务器来实现。

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

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