简体   繁体   中英

GraphQL custom Scalar validation

I just made a simple Scalar type/package for Node, graphql-scalar-json5 .

It seems to me to be working as expected

But I got a question about it

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

It got me thinking I might be doing something wrong.

While you get an error, at resolve time, if the value is Not valid.
There is no warning in GraphiQL

GraphiQL/GraphQL 错误

I'm not sure if this is limitation of custom scalar types in GraphQL. or a GraphiQL implementation detail

At 1st impression it makes sense, that if a JSON5 (or JSON) value is effectively deriving from the String type, but I never told 'GraphQL' about it, and doesn't seem to be way to do so...
How will the tool know the parameter is of the wrong type?

Taking another custom scalar, EmailAddress, from graphql-scalars

With the following Query definition

echoMail(email: EmailAddress): EmailAddress

Again, The type check only happens at runtime/resolver-time, as it needs to be parsed, by the resolver, to be validated.

Is there a better way to do this?

As an example, given the following implementation

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),
});

How would you improve it?
Does it make any difference where to validate the value?
On serialize , on parseValue , on parseLiteral ? Is there anything else to 'implement'?

Thanks

Custom type/scalar... it should be obvious that you need custom validation.

on backend/API:

Both parseValue and parseLiteral are quarded by MyScalar.from .

Already "accepted" (validated 'on input') value usually doesn't need additional validation 'on output' ( serialize ). It seams that you sometimes could use it to "correct" data/format/value but probably you would do it on resolver level (read DB - before returning data that should match type[-s]).

on graphiQL/playground:

AFAIK There is no way to inform system how to validate your custom types/scalars - simply can't be supported.

on frontend:

You have (should) to implement the same validation (equal to used on API/backend) rules before sending custom data (variables).

Tools like Graph i QL utilize introspection to obtain information about the schema the requests are being executed against. Under the hood, the introspection result is converted into a local copy of your schema and this is what's used to validate the queries written in the editor and provide autocompletion suggestions. In other words, when you make a typo and Graph i QL highlights it for you in red, it does so by validating the query locally instead of sending the request to the server.

The key here is that the Graph i QL schema is not executable -- it doesn't contain any of the custom code you used to write your schema. It has the same types as your remote schema, but it won't include any custom code those types use (like resolvers) because that information can't be communicated through introspection. So, when your query is validated by the local schema, it has no way to know whether custom scalar values are valid because it can't run the code to validate them. This is in contrast with built-in scalars like Int or String which the schema can validate because it has the code to validate them because they're, well, built-in:)

This is one of several reasons you don't want to utilize custom scalars unless absolutely necessary -- they cannot be validated by clients, editor plugins, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM