Skip to content

Fix parsing of default values in buildASTSchema, extendSchema and buildClientSchema #903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from

Conversation

IvanGoncharov
Copy link
Member

In the current implementation buildASTSchema, extendSchema and buildClientSchema register following stubs as parseLiteral and parseValue:

    return new GraphQLScalarType({
      // ...

      // Note: validation calls the parse functions to determine if a
      // literal value is correct. Returning null would cause use of custom
      // scalars to always fail validation. Returning false causes them to
      // always pass validation.
      parseValue: () => false,
      parseLiteral: () => false,
    });

Because of that, graphql-js can't correctly parse default values of custom scalar types:

scalar CustomScalar

type Query {
  someField(someArg: CustomScalar = 5): String
}

So to clarify. You can override those functions after the schema is built, but the default value from IDL will be lost.

To illustrate this I've added a test case in the first commit of this PR and here is the result:
screen shot 2017-06-09 at 11 20 21 pm

This PR solves this problem by providing reasonable defaults for parseLiteral and parseValue.

Copy link
Contributor

@leebyron leebyron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some questions inline

* Create a JavaScript value from a GraphQL languate AST representation
* of Scalar.
*/
export function scalarValueFromAST(astValue: ValueNode): mixed {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very similar to valueFromAST - can that be used instead?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this function is for scalars, then it should likely not support LIST or OBJECT, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very similar to valueFromAST - can that be used instead?

valueFromAST builds value based on the type definition it accepts as the second argument.
In a case of a scalar, there is no such type definition.

If this function is for scalars, then it should likely not support LIST or OBJECT, correct?

AFAIK, the spec doesn't explicitly forbid complex scalars as LIST or OBJECT. Moreover, it's a widespread practice to create such scalars. More details in this PR:
graphql/graphql-spec#325

@@ -333,7 +334,7 @@ export class GraphQLScalarType {
// Parses an externally provided value to use as an input.
parseValue(value: mixed): mixed {
const parser = this._scalarConfig.parseValue;
return parser && !isNullish(value) ? parser(value) : undefined;
return parser && !isNullish(value) ? parser(value) : value;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a value parses as nullish, shouldn't it return clearly as undefined to not be confused with a true null value?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -58,6 +58,10 @@ export { valueFromAST } from './valueFromAST';
// Create a GraphQL language AST from a JavaScript value.
export { astFromValue } from './astFromValue';

// Create a JavaScript value from a GraphQL languate AST representation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

language

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@IvanGoncharov IvanGoncharov force-pushed the astValueToData branch 2 times, most recently from 8534882 to f9bcc32 Compare June 21, 2017 18:35
@leebyron
Copy link
Contributor

leebyron commented Dec 1, 2017

Thanks for making this happen, Ivan. Great improvement

leebyron added a commit that referenced this pull request Dec 1, 2017
Closes #903

commit 0062abf
Author: Lee Byron <[email protected]>
Date:   Fri Dec 1 12:49:38 2017 -0800

    Amends this PR with a few additions:

    * Generalizes building a value from an AST, since "scalar" could be misleading, and supporting variable values within custom scalar literals can be valuable.

    * Replaces isNullish with isInvalid since `null` is a meaningful value as a result of literal parsing.

    * Exports this new utility from the top level

commit 0ca6cf0
Merge: 37717b8 78e69d6
Author: Lee Byron <[email protected]>
Date:   Fri Dec 1 11:57:55 2017 -0800

    Merge branch 'astValueToData' of https://github.com/APIs-guru/graphql-js into APIs-guru-astValueToData

commit 78e69d6
Author: Ivan Goncharov <[email protected]>
Date:   Sun Jun 11 01:07:47 2017 +0300

    Fix 'serialize' stub used in buildASTSchema

commit a0688c6
Author: Ivan Goncharov <[email protected]>
Date:   Fri Jun 9 23:24:55 2017 +0300

    Provide reasonable default version of 'parseLiteral'

commit 313d66e
Author: Ivan Goncharov <[email protected]>
Date:   Fri Jun 9 23:22:49 2017 +0300

    Add test for building client schema with default value on custom scalar
@IvanGoncharov IvanGoncharov deleted the astValueToData branch March 9, 2018 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants