Skip to content
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

Enum in subscription 'query' #77

Closed
chelliwell opened this issue Sep 16, 2019 · 13 comments
Closed

Enum in subscription 'query' #77

chelliwell opened this issue Sep 16, 2019 · 13 comments
Milestone

Comments

@chelliwell
Copy link
Contributor

I can add a string argument to a subscription:

        public class MessageSubscription
        {
        [GraphQLArguments("src", "String", "fromSrc", IsRequired = true)]
        public Message subRd { get; set; }
        }

        public class Message
        {
            public string src { get; set; }
            public Record record { get; set; }
        }


        var operation = await graphQLSubscriptionClient.ExecuteOperation<MessageSubscription>(new GraphQLQueryArgument("fromSrc", "SB"));

Gives a query:

"{\"query\":\"subscription subRd{subRd(src:\\\"SB\\\"){src record}}\"}"

Trouble is, the argument actually needs to be an enum:

        public enum RdSrc
        {
            SB,
            XB
        }

for query

"{\"query\":\"subscription subRd{subRd(src:SB){src record}}\"}"```

Is this possible..?

@sahb1239
Copy link
Owner

When executing the operation you should use the enum in the GraphQLQueryArgument. For example:

var operation = await graphQLSubscriptionClient.ExecuteOperation(new GraphQLQueryArgument("fromSrc", RdSrc.SB));

This should generate the correct query.

@chelliwell
Copy link
Contributor Author

Hmmm, it's making something 'weird'....
What should I put in the argumentType?

[GraphQLArguments("src", 
    "String",    // <- ??
    "fromSrc", IsRequired = true)]

@sahb1239
Copy link
Owner

You should put the name of the enumtype in GraphQL. You can find this name using introspection for example using GraphQL Playground or GraphiQL. It could for example be RdSrc.

@chelliwell
Copy link
Contributor Author

Ok (can't believe I hadn't tried that!). Because of the IsRequired, it seems I need "RdSrc!".

I'm still finding it difficult to tie up both ends though. The above sends 0 as the arg value, which my server rejects since it isn't SB or XB. I can get the textual form of the enum, but that is then a string and so (obviously) gets quoted by GraphQLQueryArgument....
Although the [Apollo] server docs suggest the enums can have alternative values, I've not got it to accept 0 or "XB" - and in any case that would kinda ignore the use of nicely typed enums?

@chelliwell
Copy link
Contributor Author

This may or may not be a similar thing, but I'm also having trouble doing an introspection ValidateGraphQLType on a query which also takes this enum as an argument:
"Argument at QryRdByEmitter has a invalid type. Expected is , actual is RdSrc!."

@sahb1239
Copy link
Owner

sahb1239 commented Sep 16, 2019

Hello,

You can use EnumMember (Newtonsoft.Json).

public enum RdSrc
{
   [EnumMember(Value = "SB")]
   SB,
   [EnumMember(Value = "XB")]
   XB
}

Would you create a issue on the other issue with the introspection? This is clearly a bug

@chelliwell
Copy link
Contributor Author

Still trying to work through that suggestion, but isn't it going to still have the problem of giving something of type string, and end up quoted? i.e.

  subscription subRd{subRd(src:"SB"){src record}}

whereas an enum param needs to be

  subscription subRd{subRd(src:SB){src record}}

I suspect some additional classes/types would be needed to support this?

sahb1239 added a commit that referenced this issue Sep 17, 2019
@sahb1239
Copy link
Owner

I have found out the problem is the default way Newtonsoft.Json serializes enums. I have created some testcode which shows how it's possible to override the default behaviour.

@chelliwell
Copy link
Contributor Author

I'm not surprised that its an awkward case - in any programming language an enum is just used as-is, as in GraphQL. But through any intermediate serializing like JSON/XML/etc, they tend to quote the 'values'

@sahb1239
Copy link
Owner

You are completely correct. According to the spec it should be "values are represented as unquoted names".

This should therefore be handled in this library possible by providing a default custom JsonConverter.

@sahb1239
Copy link
Owner

I have found the problem in GraphQLQueryGeneratorFromFields. Currently it uses JsonConvert to serilize the value at line 246. This should be handled in a better way.

@sahb1239 sahb1239 added this to the 2.2.0 milestone Sep 17, 2019
@sahb1239
Copy link
Owner

It should now be fixed for all inlined arguments. I'm not sure if it should also be updated for variables would you check if your server has the same problem for not inlined arguments?

[GraphQLArguments("src", "RdSrc!", "fromSrc", inlineArgument: false, isRequired: true)]

@chelliwell
Copy link
Contributor Author

I've tried both query and subscription, with inline both true and false - all four cases are being generated correctly, and accepted by my server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants