How to have GraphQL enum resolve Strings
Asked Answered
R

1

10

Previously, I just typed my input KeyInput as mode: String!, and I'm looking to change the type from String! to a custom enum.

I have the tried following schema:

enum Mode= {
    test
    live
}

input KeyInput = {
    mode: Mode!
}

type Key {
    name,
    mode
}

type Query {
    Keys(input: KeyInput): [Key]
}

And my query looks like this:

query{
     Keys(input: {mode: "test"}){
        name
     }
}

However, I get the following error:

      "message": "Expected type Mode!, found \"test\"; Did you mean the enum value test?"

Is it possible to have enum values resolve String values? If I remove the quotes from the input, it will work. However, I need to be able to continue to resolve the Mode as Strings.

Rebeccarebecka answered 12/3, 2019 at 3:8 Comment(2)
It's not clear what you mean by "continue to resolve the Mode as Strings". Can you please clarify why omitting the quotation marks in the query is a problem for you?Bondy
Sorry; If i were to query Keys like so without quotes: Keys(input: mode: test}), GraphQL will have no problems resolving test. However, I would like it to resolve test in quotes as "test".Rebeccarebecka
B
10

From the spec:

GraphQL has a constant literal to represent enum input values. GraphQL string literals must not be accepted as an enum input and instead raise a query error.

Query variable transport serializations which have a different representation for non‐string symbolic values (for example, EDN) should only allow such values as enum input values. Otherwise, for most transport serializations that do not, strings may be interpreted as the enum input value with the same name.

In other words, when using an enum as an input, if you're using it as a literal value, like this:

Keys(input: { mode: test }) {
  name
}

the enum value (test in this case) cannot be quoted, unlike Strings literals, which must be surrounded by double quotes.

On the other hand, if you're using a variable to substitute an enum value, you'll set the value of the variable to a string, just like you would for a regular String value:

Keys(input: { mode: $mode }) {
  name
}

// in your component...
variables: {
  mode: 'test'
}

Because JSON doesn't include the concept of enum values, whenever we deal with a JSON context (for example, when declaring variables, or when returning the data for our request), enum values are simply serialized as string values.

All that aside, if you're using Apollo as a client, whether you have to include the quotation marks or not should be irrelevant -- if you need to substitute the value for the mode input field, you should be using variables to do so, in which case (as shown above), you would be passing in a string value regardless.

Bondy answered 12/3, 2019 at 3:41 Comment(5)
Perfect answer, thank you! And for the link to the spec as well; I hadn't thunk to look there, as I was too focused on apollo-server docs.Rebeccarebecka
I was hoping to keep a consistent way to have my graphiql users be able to use Strings along enums. For example, if I were to have name: String! along side Mode: enum, the query would not seem consistent: Keys(input: { name: "Jim", mode: test})Rebeccarebecka
Instead, I'd prefer it be able to be queried like this: Keys(input: { name: "Jim", mode: "test"})Rebeccarebecka
Yes, from the perspective of existing consumers of your API, changing the field to an enum would be a breaking change.Bondy
Sadly this doesn't work for meStern

© 2022 - 2024 — McMap. All rights reserved.