const typeDefs = `
enum AllowedColor {
RED
GREEN
BLUE
}
type Query {
avatar(
aString: String = "test"
anArrayOfEnum: [AllowedColor!] = [RED]
anEnum: AllowedColor = RED
): String
}
`;
const resolvers = {
AllowedColor: {
RED: '#f00',
GREEN: '#0f0',
BLUE: '#00f',
},
Query: {
avatar: (root, args) => {
const anArrayOfEnum = args.anArrayOfEnum.join(', ');
return `aString: ${args.aString} - anArrayOfEnum: ${anArrayOfEnum} - anEnum: ${args.anEnum}`;
},
}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
Got: aString: test - anArrayOfEnum: RED - anEnum: RED
Expected: aString: test - anArrayOfEnum: #f00 - anEnum: #f00
Yep! This is definitely an issue. If anyone wants to work on this, I've spun up this reproduction in a glitch example: https://glitch.com/edit/#!/enum-defaults
Closing this. This is an issue with graphql-js. I set up a reproduction using graphql-js and confirmed this here.
Feel free to open an issue on that repo for this 馃憤
@JakeDawkins
Hi. I am not sure I follow your line of thought on this. graphql-tools uses graphql.js as its underlying implementation.
According to the issue you referenced above, there is a way of using Enums in graphql.js, which is not being employed in grapqhl-tools. It requires adding defaultValue to any filed with an enum and a default value:
const schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: () => ({
avatar: {
type: GraphQLBoolean,
args: {
anEnum: {
type: allowedColor,
defaultValue: '#f00',
// ^ Changed to value
},
},
resolve: (root, args) => (args.anEnum === '#f00' ? false : true),
},
}),
}),
});
I'm not sure if this is a graphql-tools issue, an apollo-graphql issue, or a graphql.js issue, but if I pass the default value in the internal representation, the resolver receives undefined.
It's a graphql-tools v4 issue, fixed in v5, construct your schema with latest graphql-tools v6 makeExecutableSchema and then pass to ApolloServer using schema option
@yaacovCR @dandv It looks like there's two separate issues here.
First, there's what I think is a genuine issue with validating default values. For example, this should crash but doesn't:
echo(status: Int = "abc"): String!
This is why you're receiving undefined -- using a literal 2 this way is not valid. You can only utilize the actual enum values when using SDL. The "internal values" are used only inside your resolvers. However, GraphQL shouldn't let you pass in a 2 in the first place, just like it shouldn't let you assign "abc" as the default value for an Int argument.
I think this is mostly a graphql-js problem, because I can create a schema programmatically without using graphql-tools and still get away with passing in default values of the wrong type.
The other issue was, like you showed in the original sandbox, when a default value is correctly provided and then used, it wasn't converted to its internal representation, unlike when the argument is explicitly provided. However, this appears to be fixed.
Thanks @danielrearden !!!
@danielrearden: so the workaround is to pass APPROVED as the default parameter in the schema, and look up the string against my enum values in the resolver, until graphql.js fixes this?
@yaacovCR: I was using graphql-modules in production anyway, which uses graphql-tools v5 (not 6 though) and still saw the undefined error.
@dandv @yaacovCR I opened this issue to address the lack of validation of argument default values
@dandv I don't think you need a workaround. If I execute the query { echo } on your newer sandbox, it correctly passes 2 down to the resolver. In other words, by setting the default as APPROVED, you are seeing the correct behavior.
Thanks @danielrearden!
@yaacovCR: my situation was confused by using graphql-modules. I've isolated the bug to graphql-modules specifically - https://github.com/Urigo/graphql-modules/issues/1176.