SAHB.GraphQLClient icon indicating copy to clipboard operation
SAHB.GraphQLClient copied to clipboard

How do I transform the names of parameters for a class that is used as a query argument?

Open WesToleman opened this issue 4 years ago • 3 comments

Background

I'm trying to pass the variables { "foo": {"fooNumber": "0123456789", "systemCode": "BAZ"} } to this query

query GetFooId(
  $foo: FooNumber
) {
  foobeta (foo: foo) {
    id
  }
}

What works

If I use a class that with parameters that are named identically it works.

var = new { number = "0123456789", systemCode = FooSystemType.BAZ };
var arg = new GraphQLQueryArgument("foo", foo));

Issue

However it does not work with a traditionally named class because parameter names are not transformed.

public class FooNumber
{
    [GraphQLFieldName("fooNumber")]
    public string Number { get; set; }

    public FooSystemType SystemCode { get; set; }
}

It generates an SAHB.GraphQLClient.Exceptions.GraphQLHttpExecutorServerErrorStatusCodeException because of a BadRequest.

Generated Query

Query

query($foo:FooNumber){foobeta(foo:$foo){id}}",

Variables

"foo": {
    "Number": "0123456789",
    "SystemCode": "BAZ"
}

Response

{
    "errors": [
        {
            "message": "Variable \"$foo\" got invalid value { Number: \"0123456789\", SystemCode: \"BAZ\" }; Field fooNumber of required type String! was not provided."
        },
        {
            "message": "Variable \"$foo\" got invalid value { Number: \"0123456789\", SystemCode: \"BAZ\" }; Field systemCode of required type FooSystemType! was not provided."
        },
        {
            "message": "Variable \"$foo\" got invalid value { Number: \"0123456789\", SystemCode: \"BAZ\" }; Field \"Number\" is not defined by type FooNumber."
        },
        {
            "message": "Variable \"$foo\" got invalid value { Number: \"0123456789\", SystemCode: \"BAZ\" }; Field \"SystemCode\" is not defined by type FooNumber. Did you mean systemCode?"
        }
    ],
}

Query classes

public class FooQuery
{
    [GraphQLArguments("foo", "FooNumber", "foo")]
    public FooBeta FooBeta { get; set; }
}

[GraphQLFieldName("foobeta")]
public class FooBeta : Foo
{
}

public class Foo
{
    public string Id { get; set; }
}

[JsonConverter(typeof(StringEnumConverter))]
public enum FooSystemType
{
    [EnumMember(Value = "BAZ")]
    BAZ,
}

WesToleman avatar May 06 '20 04:05 WesToleman

Hello @WesToleman

Currently the arguments are serilized using Newtonsoft.Json and therefore you should use [JsonProperty("fooNumber")] instead of [GraphQLFieldName("fooNumber")].

Please see the example here: https://github.com/sahb1239/SAHB.GraphQLClient/commit/e53fa7e7564845d532e23b6ca4d3493cf1054644

In order to be able to support GraphQLFieldName the dependency on Newtonsoft.Json must be removed. This could be done in a later release.

sahb1239 avatar May 08 '20 08:05 sahb1239

Thanks for the example @sahb1239. Can JsonProperty and GraphQLFieldName be used on the same property? I can imagine there might be scenarios where FooNumber is part of the query model. It's not a major issue for me at the moment but I would like to know if it does get solved in a future release.

WesToleman avatar May 11 '20 01:05 WesToleman

Hello @WesToleman It should be possible to use both attributes on the same property.

I can't at the moment give you an exact release date, but I will look at it when I get the needed time.

sahb1239 avatar May 11 '20 18:05 sahb1239